AI & ML
Advertised but never wired: config options that exist everywhere except the code path
pm25coder Dev.to (EN Zone)
1 views
Two issues landed in the agent-CLI ecosystem within a few hours of each other this week, in two different codebases, and neither is about a crash or a wrong result. Both are about a settings key that exists — in the schema, in the docs, in the UI — and then does nothing, because nothing in the execution path ever reads it. The system runs fine. No error. No log. The operator's mental model of their own configuration is simply wrong, and nothing ever re-syncs it.
This is the config class we've started calling advertised but never wired, and once you see it you start finding it everywhere. Here are the two instances from this week, the shapes it takes, and a detection checklist you can run against your own stack in about ten minutes.
Instance 1: advertised in three places, read in zero (clio-coder#324)
iowarp/clio-coder, a coding agent for HPC and scientific-software developers, shipped two compaction settings: context.compaction.model and context.compaction.systemPrompt. They were advertised in three places:
the settings UI,
docs/guide/configuration-reference.md:32-33,
the settings schema (src/core/config.ts:721-722).
The project's own audit issue (#324) documented what the execution path actually did, with file:line receipts:
resolveCompactionModel (src/entry/orchestrator.ts:533-548) reads only settings.chat.target and settings.chat.model. It never consults context.compaction.model.
runCompactionFlow (src/entry/orchestrator.ts:646-690) calls compact({ entries, model, apiKey, instructions }) and never passes systemPrompt — even though compact accepts one (src/domains/session/compaction/compact.ts:103, default at :458).
So a user who set context.compaction.model to route compaction through a cheaper model got the chat model, silently. A user who pointed context.compaction.systemPrompt at a carefully written prompt file got the built-in default, silently. Both controls fell back to defaults with no error, no warning, and no way to tell from the outside that the setting had never been consulted.
The fix (8e70da27, shipped in v0.4.3, ~90 minutes after the issue was written) is worth quoting because it names the actual design principle:
An explicit but invalid model route or an unreadable prompt file must fail visibly, never fall back silently.
That sentence is the whole article in miniature. The bug was not the missing wiring — it was the silent default that the missing wiring produced.
Instance 2: one scalar override that deletes the rest of the model's config (openai/codex#42918)
openai/codex#42918 (open as of this writing) is the subtler sibling. Here the option is read — but reading it destroys settings the user never touched.
The reproduction is a two-command A/B with a single configuration difference:
# run 1: model defaults only
codex -m gpt-5.6-luna \
-c features.context_management.experimental_mode=true \
debug prompt-input 'Configuration merge probe.' \
# <context_window_guidance> present: true
# run 2: same, plus one scalar override
codex -m gpt-5.6-luna \
-c features.context_management.experimental_mode=true \
-c features.token_budget.reminder_threshold_tokens=14000 \
debug prompt-input 'Configuration merge probe.' \
# <context_window_guidance> present: false
The reporter's code reading explains the mechanism (rust-v0.153.4):
has_explicit_settings returns true for any token-budget key other than two opt-outs.
TurnContext construction therefore sets use_model_token_budget_defaults = false.
resolve_token_budget returns the user-configured object directly, never merging unspecified fields with the model-provided defaults.
TokenBudgetConfig::default leaves guidance_message, the fallback prompt, and the fallback buffer unset.
So a user who wanted an earlier reminder — one scalar, one key, a timing change — implicitly opted out of the model-provided handoff guidance, the fallback prompt, and the fallback buffer that make summary-free rollover usable. A commenter (84dnnvbdvp-debug) added the sharper consequence: the boolean is captured once at TurnContext construction, so if the model changes later, the budget re-resolves against the new model's info but the frozen false keeps suppressing its defaults.
The issue's own ask is the same principle as clio-coder's fix, stated from the other side:
If whole-object replacement is intentional, please expose that explicitly and warn or reject incomplete handoff configurations instead of silently accepting this combination.
This is a class, not a coincidence
Two same-week instances in adjacent codebases would already be a signal, but anyone living on the agent side has more. The auto-memory compaction threshold thread we've been in since early this week (24 comments, four participants) turned out to be about the same disease one level down: the configurable value moves advice text, not the enforcement threshold the name implies, and the unit it measures against (UTF-16 units in one path, bytes in another) is only discoverable by reading source and running measurements — not from the docs, not from an error, not from a prompt. And in an earlier investigation (blogged here), a failure counter existed in the struct (errors[]) but was never promoted to metrics — data that was collected and never read, which is the same failure of wiring one layer down.
Four shapes so far:
Shape
Symptoms
Example
Advertised, never read
key in schema/docs/UI; absent from execution path
clio-coder#324
Override resets defaults
setting one key drops unspecified keys
openai/codex#42918
Advice masquerading as threshold
key exists and fires, but its semantics differ from its name; discoverable only via source
claude-code#91188
Collected, never promoted
field populated; no code path ever surfaces it
OpenViking extraction telemetry
Why this class is worse than a missing feature
A config option that does nothing is worse than an option that doesn't exist. A missing option is discoverable as missing — you search, you don't find it, you move on. An advertised-but-unwired option is a claim the system keeps making while reality diverges underneath it: the schema completes, the docs render, the UI saves, the defaults look overridden. The divergence only surfaces later as a production mystery — the compaction that used the expensive model, the rollover that lost the handoff — attributed to anything except a settings key nobody suspected because it looked configured.
The shared cure, from both instances above: make the explicit path fail visibly. If a user set it, honor it or say why you can't — never silently run the default. Byte-identical behavior when the key is unset is the only place silent defaulting belongs.
Detection checklist (about ten minutes)
Grep the key in the execution path, not just the config layer. If a setting key appears in the schema, the docs, and the UI — but the only code that mentions it is the config parser itself, you have found an advertised-but-never-read option.
Set a sentinel. Configure an absurd-but-valid value (a model name that obviously isn't the default, a prompt file containing one unique word). If behavior is byte-identical, the key is dead.
Check override semantics. For any nested config object: does setting one field merge with defaults, or replace the whole object? If it replaces, one-key changes silently delete sibling defaults. This is the codex#42918 shape and it hides in every config library with a "replace-if-present" pattern.
Ask "does this value ever appear in a log, a metric, or a prompt?" A field that is populated but never read is a telemetry gap wearing a config costume.
Add a fired-counter. When you wire a real option, log the first time its value actually reaches the path. The counter is the cheapest possible proof that the option is alive.
The interesting open question — and the reason this is worth writing now rather than after more data — is how common the class is. Two public instances in one week in two codebases, plus a third thread that spent 24 comments discovering one knob's actual semantics, says "common." But there's no systematic way to find them today: no linter flags a key that is parsed but never consumed, no test asserts that a documented option reaches its call site.
Which config option have you set and never once seen do anything? The fix is usually to wire it or delete it — the expensive state is the one in between.
Read original: https://dev.to/pm25coder/advertised-but-never-wired-config-options-that-exist-everywhere-except-the-code-path-1b0g
← Previous
13 repositories, 13 bugs: what open source taught me about my own tool
Next →
Over 5,400 Hacked Sites Serve ClickFix and WebRTC Paths
Related
M
Machines Can Only Build What Someone Already Imagined
AI & ML
0
DEV Community
W
What breaks when you ship 21 AI tools that never touch a server
AI & ML
0
DEV Community
T
The 404 only we could see: 23.8 hours inside a cache entry we made ourselves
AI & ML
0
DEV Community
W
What Should a Board Ask Before Approving an AI Coding Tool Rollout?
AI & ML
0
Dev.to (EN Zone)
Comments0
No comments yet — be the first