← all articles

A Proxy Is Right Until Someone Changes Their Settings

A Proxy Is Right Until Someone Changes Their Settings

If a feature needs to know one thing and you hand it a value that merely correlates with it, the feature will be right until the day somebody breaks the correlation. Then it will be confidently wrong, and the person who finds out will be a user, not you. The fix is rarely clever. Work out what the feature actually means, and give it a source that says exactly that.

I came across a small, clean example this week. An app has an illustrated scene that changes with the time of day: sun and warm light by day, moon, stars and a few night creatures after dark. Separately, the app has an overall "sky" setting, a coarse band of dawn, day, dusk or night that drives the colour theme. When the scene was built, it asked that sky band what time it was. That made sense. The band was already there, it was already computed from the clock, and it looked like the answer.

It was the answer for most people, most of the time. But the sky band had a second job. When a phone or browser is set to dark mode, the app treats the sky as night, because dark mode needs a night palette. So a user who preferred dark mode opened the app at nine in the morning and found the moon, the stars and the crickets out. Nothing had crashed. No request had failed. The scene was faithfully reporting what the sky band said, and the sky band was reporting a preference rather than the time.

Two meanings sharing one name

What went wrong here is not really a bug in any single line. The word "night" had quietly come to mean two things: "it is after seven in the evening" and "this user wants dark surfaces". For a long time those meanings agreed often enough that nobody had to separate them. Dark mode users are not rare, though, and the moment one of them looked at a scene that was supposed to follow the sun, the two meanings pulled apart.

This is the general shape of a proxy failure. You want to know X. You can cheaply read Y, and Y is correlated with X. So you read Y. Everything works in the demo, in the tests, and for the person who wrote it, who probably uses the default settings. The weakness only appears when someone sits in the gap between X and Y, and that is usually a person with a preference, a locale, a timezone, an accessibility setting or an unusual device. Those are exactly the people you least want to surprise.

I think we sometimes confuse reuse with good design. Reusing a signal feels thrifty: one source of truth, no duplicate logic. But a source of truth is only truthful about the thing it was built to represent. Borrowing it for a neighbouring question means you are quietly asserting that the two questions will always have the same answer. That is a claim, and it deserves the same scrutiny as any other.

Why the usual safety nets missed it

It is worth being honest about why this kind of defect survives. The logs were clean, because nothing failed. The tests were green, because they forced the sky band to day or night and checked that the scene responded, which proved the scene obeyed the band and said nothing about whether the band was the right input. A test that agrees with the implementation's assumption is not a check on that assumption.

The only thing that exposed it was somebody looking at the screen in dark mode at a time of day when it plainly made no sense. That is a very human kind of detection. It is also unreliable, which is why it is better to turn the discovery into a test that encodes the real requirement.

The fix is to say what you mean

The repair was modest. The scene stopped reading the shared band and began working out its own time of day directly from the clock, ignoring the appearance setting entirely. The rest of the app kept its sky band and its dark theme exactly as before, because for those purposes the band was correct. On the web side, the scene also schedules itself to turn over at the next boundary, so a page left open overnight still changes at the right moment instead of waiting for a refresh.

The test was changed in the way I find most useful: it now states the requirement in the terms a user would. At nine twenty in the morning, with the app's sky set to night, the scene shows the sun. Written that way, the test fails for the right reason if anyone ever tries to be thrifty again.

Notice what was not done. Nobody ripped out the sky band, or invented a general theory of time. The scene needed a fact about the clock, so it asks the clock. The theme needed a preference, so it asks the preference. Two questions, two sources, and each one is allowed to be wrong only in ways that matter to its own feature.

A practical way to catch it earlier

When you reach for an existing value, ask what it was created to mean, and whether that is what you mean. If the honest answer is "close enough", look for the setting, mode or user choice that would make it not close enough. Dark mode, reduced motion, a different timezone, a device language, a corporate proxy, a user who has switched off a permission: each of these is a lever someone can pull to separate two things you assumed were one.

There is a commercial angle too, although it is easy to miss. The cost of these defects is not the engineering time to fix them, which was small here. It is the small loss of trust when a product that is meant to feel considered shows the moon at breakfast. People forgive bugs they can understand. They are less forgiving of a product that looks as though it has not noticed them, and a person who chose dark mode has told you something about themselves. Getting that wrong feels, quite reasonably, like not being listened to.

So I have come to prefer the slightly less economical option: when two features need different truths, give them different inputs, even if today they happen to agree. It costs a few lines. It saves you from explaining to someone why your app thinks it is midnight at morning tea.

Matthew Ratcliffe, software developer and architect, Ballarat
Senior Software Engineer & Architect

20+ years across the technology stack — from greenfield builds to brownfield rescues. Based in Ballarat, VIC, focused on AI, healthcare and high-risk data systems. Full resume →

Share your thoughts