You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
bug(provider-switch): switching OpenCode → Claude with a pasted image writes a foreign 'file' block and the Claude API rejects every later turn #999
After an OpenCode → Claude switch, the projected Claude transcript contains only content blocks the Claude Messages API accepts. An image the user pasted in OpenCode arrives as a Claude image block ({type:'image', source:{type:'base64', media_type, data}}), or is dropped with a reported loss. The new Claude session keeps working.
Actual behaviour
The OpenCode file part is copied into the Claude transcript verbatim:
Claude first answers twice with "I can't view images in this session" (the block is not an image to it), and as soon as the user pastes the screenshot again the whole session fails with:
API Error: 400 messages.985.content.1: Input tag 'file' found using 'type' does not match any of the
expected tags: 'advisor_tool_result', …, 'document', 'image', …, 'text', …, 'tool_use', …
(recorded as an isApiErrorMessage assistant record, apiErrorStatus: 400, 2026-09-18 20:27:17Z, Claude Code 2.1.277). The invalid block stays in history, so every subsequent turn in that Claude session gets the same 400. The user's only way out was a switch back to OpenCode, which then hit #998.
Root cause (in agent-transcript-parser)
claudeMessageContent in src/claude/project/nativeResume.ts pushes { ...item.value } for every neutral image / document content item without checking that the value is a Claude-shaped block. The OpenCode decoder wraps its native file part as {kind:'image', value: part} and the Codex decoder wraps input_image items the same way, so both foreign shapes reach the Claude file unchanged. The other two projectors already convert in the opposite direction (codexImage, filePart); the Claude projector is the only one that emits a block the target's API is known to reject.
Impact
Any OpenCode → Claude or Codex → Claude switch of a conversation that contains a user image produces a Claude session that breaks on its next turn. Data-integrity risk: the user sees a working pane with full history and only discovers the corruption when they submit.
Activity
fix(provider-switch): make the loss notice readable and take the merg…