[BUG] Cached experiment payload injects system-prompt directives indefinitely; `CLAUDE_CODE_DISABLE_NONESSENTIAL_TRAFFIC` gates the fetch but not the read
Preflight Checklist
- [x] I have searched existing issues and this hasn't been reported yet
- [x] This is a single bug report (please file separate reports for different bugs)
- [x] I am using the latest version of Claude Code
What's Wrong?
A server-delivered experiment payload, cached in ~/.claude.json → clientDataCacheSlots, injects
directives into the session system prompt — in my case:
Do not call the AgentTool unless the user requested it Do not use workflows or deep-research unless the user requested it
Two distinct problems:
- The cache has no TTL on the read path. The slot's
attimestamp is consulted only when
deciding whether to refetch; the accessor that feeds the injected string into the system
prompt returns slot?.data ?? null unconditionally, gated only by an is-first-party-auth
check. Setting CLAUDE_CODE_DISABLE_NONESSENTIAL_TRAFFIC=1 skips the bootstrap fetch
([Bootstrap] Skipped: Nonessential traffic disabled) and then returns early without touching
the cache — so a previously cached experiment payload keeps applying forever. The only
remedy is hand-editing ~/.claude.json.
- No disclosure or opt-out surface. The injected directive materially changes agent behavior
(it suppressed subagent dispatch in a workflow that depends on fresh-agent reviews), but it is
invisible to the user: nothing in /config, /status, or the session UI indicates an
experiment is modifying the system prompt, and the payload carries no user-visible expiry.
Details confirmed by inspecting the v2.1.218 binary (minified identifiers, cited for the
maintainers' benefit): the injection reads Q0()?.tengu_heron_brook with a Statsig dynamic-config
fallback and emits a tengu_heron_brook_applied telemetry event; Q0() readsclientDataCacheSlots[<slot>] via tKi() → xto(e,t)?.data ?? null with no freshness check; the
gate predicate is eFs() (provider check only); the fetch-side guard is da() in ZZ_().
What Should Happen?
- With
CLAUDE_CODE_DISABLE_NONESSENTIAL_TRAFFIC=1set, previously cached experiment payloads
should not be applied — the env var should gate consumption, not just acquisition. At minimum
the read path should honor the same staleness window the fetch path uses, so a stale slot ages
out instead of applying indefinitely.
- Prompt-modifying experiments should be visible to the user (e.g. surfaced in
/statusor
/config) and carry an expiry the client enforces.
Error Messages/Logs
Cached payload, from `~/.claude.json → clientDataCacheSlots["bi1-e88e74643cfd4075"]`
(slot tagged `entrypoint: cli`, `model: claude-opus-4-8`, org UUID redacted, `at` = 2026-07-23):
{
"cedar_lagoon": { "claude-fable": true, "claude-mythos": true },
"convolute_arcades": true,
"experimentKey": "claude_code_vellum_thicket_experiment",
"atis": "vellum-thicket-quarry",
"tengu_marl_cormorant": true,
"tengu_gault_kestrel": true,
"tengu_thistle_grebe": "no_nudges",
"tengu_bison_cairn": true,
"tengu_larch_cistern": true,
"tengu_heron_brook": "Do not call the AgentTool unless the user requested it\nDo not use workflows or deep-research unless the user requested it",
"cedar_basin": "2026-08-31"
}
Steps to Reproduce
Reproducing requires an account bucketed into a prompt-injecting experiment (e.g.claude_code_vellum_thicket_experiment); the no-TTL defect itself is visible from the code path
alone.
- Start Claude Code (v2.1.218, first-party auth) while bucketed into the experiment. The
bootstrap fetch caches the payload into ~/.claude.json → clientDataCacheSlots.<slot>.data,
including the tengu_heron_brook system-prompt injection.
- Observe the directive in effect: the agent declines to dispatch subagents unprompted and, when
asked why, cites an instruction of the form "Do not call the AgentTool unless the user
requested it".
export CLAUDE_CODE_DISABLE_NONESSENTIAL_TRAFFIC=1and start a new session. The fetch is
skipped, but the cached slot is still read and the directive still applies — on every
subsequent session, indefinitely, since nothing ever expires or clears the slot.
- Only deleting the slot by hand (
jq 'del(.clientDataCacheSlots)' ~/.claude.json) removes the
injected instruction.
Claude Model
Opus
Is this a regression?
I don't know
Last Working Version
_No response_
Claude Code Version
2.1.218
Platform
Anthropic API
Operating System
macOS
Terminal/Shell
Terminal.app (macOS)
Additional Information
Impact: the injected directive silently degraded a development pipeline that depends on
subagent-based review dispatch. I understand the directive's content is Anthropic's
prerogative to test; the bug is the delivery mechanism — an undisclosed, unexpirable,
opt-out-resistant modification of the session system prompt on a paid account. Everything above
was verified by Fable against the shipped binary (GIT_SHA bce61b433bc397ce68686368abd12f545b0a013a,
build 2026-07-22).
This issue has 1 comment on GitHub. Read the full discussion on GitHub ↗