[BUG] Cached experiment payload injects system-prompt directives indefinitely; `CLAUDE_CODE_DISABLE_NONESSENTIAL_TRAFFIC` gates the fetch but not the read

Status Open
Reported on v2.1.218
Maintainer reply None cached
Activity 1 comment · opened Jul 23, 2026

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:

  1. The cache has no TTL on the read path. The slot's at timestamp 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.

  1. 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() reads
clientDataCacheSlots[<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=1 set, 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 /status or

/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.

  1. 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.

  1. 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".

  1. export CLAUDE_CODE_DISABLE_NONESSENTIAL_TRAFFIC=1 and 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.

  1. 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).

View original on GitHub ↗

This issue has 1 comment on GitHub. Read the full discussion on GitHub ↗