Summary
When Magic Context transforms messages for Anthropic sessions, it can remove redacted_thinking parts from assistant messages. Anthropic requires those blocks to be replayed unchanged, so the request is rejected with errors like:
messages.1.content.11: thinking or redacted_thinking blocks in the latest assistant message cannot be modified
Root cause
In packages/plugin/src/hooks/magic-context/strip-content.ts, stripClearedReasoning() includes redacted_thinking in the set of part types it may strip:
const CLEARED_REASONING_TYPES = new Set([thinking, reasoning, redacted_thinking]);
But the strip predicate only preserves parts that have a non-cleared thinking or text field:
const thinking = thinking in part ? (part.thinking as string | undefined) : undefined;
const text = text in part ? (part.text as string | undefined) : undefined;
return (
(thinking !== undefined && thinking !== [cleared]) ||
(text !== undefined && text !== [cleared])
);
That works for thinking / reasoning, but not for Anthropic redacted_thinking blocks, which do not use those fields. As a result, valid redacted_thinking parts fail the predicate and are removed.
Why this looks like the bug
There is already a hint elsewhere in the code that redacted_thinking should not be treated as a normal mutable reasoning part:
packages/plugin/src/hooks/magic-context/tag-content-primitives.ts
export function isThinkingPart(part: unknown): part is ThinkingLikePart {
if (part === null || typeof part !== object) return false;
const candidate = part as Record<string, unknown>;
return candidate.type === thinking || candidate.type === reasoning;
}
isThinkingPart() excludes redacted_thinking, but stripClearedReasoning() still targets it. That mismatch is what seems to break Anthropic replay.
Minimal fix
Remove redacted_thinking from CLEARED_REASONING_TYPES:
- const CLEARED_REASONING_TYPES = new Set([thinking, reasoning, redacted_thinking]);
+ const CLEARED_REASONING_TYPES = new Set([thinking, reasoning]);
Safer fix
Even with the one-line fix above, it would be good to make the preservation explicit:
if (partType === redacted_thinking) return true;
inside stripClearedReasoning() before the mutable reasoning checks.
Extra hardening suggestion
There are other transform paths that clear adjacent assistant reasoning when tagged text or tool output is rewritten. For Anthropic sessions, it may be worth adding a provider-aware rule to never mutate the latest assistant message if it contains thinking or redacted_thinking parts.
Environment where this surfaced
@cortexkit/opencode-magic-context@0.8.3
- Anthropic models in OpenCode
- Error seen during transformed follow-up requests after assistant reasoning was present
If useful, I can also open a PR with the minimal patch.
Summary
When Magic Context transforms messages for Anthropic sessions, it can remove
redacted_thinkingparts from assistant messages. Anthropic requires those blocks to be replayed unchanged, so the request is rejected with errors like:messages.1.content.11: thinking or redacted_thinking blocks in the latest assistant message cannot be modifiedRoot cause
In
packages/plugin/src/hooks/magic-context/strip-content.ts,stripClearedReasoning()includesredacted_thinkingin the set of part types it may strip:But the strip predicate only preserves parts that have a non-cleared
thinkingortextfield:That works for
thinking/reasoning, but not for Anthropicredacted_thinkingblocks, which do not use those fields. As a result, validredacted_thinkingparts fail the predicate and are removed.Why this looks like the bug
There is already a hint elsewhere in the code that
redacted_thinkingshould not be treated as a normal mutable reasoning part:packages/plugin/src/hooks/magic-context/tag-content-primitives.tsisThinkingPart()excludesredacted_thinking, butstripClearedReasoning()still targets it. That mismatch is what seems to break Anthropic replay.Minimal fix
Remove
redacted_thinkingfromCLEARED_REASONING_TYPES:Safer fix
Even with the one-line fix above, it would be good to make the preservation explicit:
inside
stripClearedReasoning()before the mutable reasoning checks.Extra hardening suggestion
There are other transform paths that clear adjacent assistant reasoning when tagged text or tool output is rewritten. For Anthropic sessions, it may be worth adding a provider-aware rule to never mutate the latest assistant message if it contains
thinkingorredacted_thinkingparts.Environment where this surfaced
@cortexkit/opencode-magic-context@0.8.3If useful, I can also open a PR with the minimal patch.