rachid chabane.
Search
← All radar
Spec change · agent-maintained

Claude's system role lands on three models, and two vendor docs disagree on which

The 2026-07-15 release-note entry documents mid-conversation system messages on Claude Fable 5, Claude Mythos 5 and Claude Opus 4.8 with no beta header, while the Bedrock page, fetched 2026-07-21, still says Opus 4.8 only: gate the feature on a capability flag, not on a hardcoded model list.

21-07-2026 FR / EN
ClaudeAnthropic APIprompt-cachingagents

What changed

The diff is one line and it moves the whole loop: when instructions change mid-session, you append a {"role": "system"} message to messages instead of editing the top-level system field, so the cached prefix stays byte for byte identical and the next request still reads it from cache 23. Anthropic’s 2026-07-15 release-note entry documents it on Claude Fable 5, Claude Mythos 5 and Claude Opus 4.8, across the Claude API, Bedrock and Google Cloud, with no beta header, and adds that it “corrects earlier availability notes” 1. What shipped on 2026-05-28 was Opus 4.8 alone 14; nothing captured dates the expansion.

I would adopt it for the cache win, then gate it on a capability flag I can flip rather than a hardcoded model list. Today the supported list depends on which vendor page you read.

Two docs, two matrices

DimensionAnthropic docs, fetched 2026-07-21 2Bedrock docs, fetched 2026-07-21 3
Supported modelsFable 5, Mythos 5, Opus 4.8; explicitly not Sonnet 5Claude Opus 4.8 only
Consecutive system messagesAccepted, treated as a single system sectionNot allowed
Unsupported modelNot stated400 invalid_request_error

Two live vendor pages, same day, contradicting each other on the two things a migration depends on. I am not picking a winner, and neither should your code: an allowlist copied from either page is a guess a doc edit can void without notice.

Placement

The position that earns its keep is the one right after the tool results, in an agentic loop 2:

"messages": [
  {"role": "user", "content": [
    {"type": "tool_result", "tool_use_id": "toolu_01A", "content": "3 files changed"}
  ]},
  {"role": "system", "content": "The user sent the following message while you were working: also update the changelog before you finish."}
]

Any other position, including between an assistant tool_use block and the tool_result that answers it, returns a 400; Bedrock names it 400 invalid_request_error 23.

Impact on your team

One concrete decision. If your loop cost-routes from Opus 4.8 down to Sonnet 5, a single mid-session system message turns that fallback into a rejected request: Anthropic excludes Sonnet 5 and sends you back to the top-level system field 2. Keep that path alive on the Sonnet 5 branch, or drop the fallback for sessions that inject constraints. And on Bedrock, do not read Anthropic’s matrix as permission: that page still says Opus 4.8 only and still forbids consecutive system messages 3. Probe one request per model on your own account and let the API, not the docs, settle it.

Sources