Description
Recently opencode become neigh-on unusable with OpenRouter for me. Most sessions end in a provider error.
It essentially breaks openrouter as provider for me, so its likely something related to my setup, but I can't figure out what.
From the logs the underlying error (using the repro below) is
{
"type": "error",
"error": {
"type": "invalid_request_error",
"message": "messages.1.content.6: `thinking` or `redacted_thinking` blocks in the latest assistant message cannot be modified. These blocks must remain as they
were in the original response."
},
"request_id": "req_011CYKKYMLyQjjKY8MRfvLHk"
}
Me and Codex did some digging and it seems that tool Parts have duplicated reasoning attached to them in the session.
The following diff solves the issue for me, but it feels a bit like treating the symptom. If its a good approach, lemme know I can turn it into a PR.
diff --git a/packages/opencode/src/session/message-v2.ts b/packages/opencode/src/session/message-v2.ts
index 178751a22..b5d41b8dd 100644
--- a/packages/opencode/src/session/message-v2.ts
+++ b/packages/opencode/src/session/message-v2.ts
@@ -488,6 +488,24 @@ export namespace MessageV2 {
})
export type WithParts = z.infer<typeof WithParts>
+ function metadata(input: Record<string, any> | undefined): Record<string, any> | undefined {
+ if (!input) return input
+
+ const prune = ["reasoning", "reasoning_content", "reasoning_details"]
+ const result: Record<string, any> = Object.fromEntries(
+ Object.entries(input)
+ .map(([provider, value]) => {
+ if (typeof value !== "object" || value === null || Array.isArray(value)) return [provider, value]
+ const next = Object.fromEntries(Object.entries(value).filter(([key]) => !prune.includes(key)))
+ if (Object.keys(next).length === 0) return undefined
+ return [provider, next]
+ })
+ .filter((entry): entry is [string, unknown] => !!entry),
+ )
+ if (Object.keys(result).length === 0) return undefined
+ return result
+ }
+
export function toModelMessages(input: WithParts[], model: Provider.Model): ModelMessage[] {
const result: UIMessage[] = []
const toolNames = new Set<string>()
@@ -608,7 +626,7 @@ export namespace MessageV2 {
assistantMessage.parts.push({
type: "text",
text: part.text,
- ...(differentModel ? {} : { providerMetadata: part.metadata }),
+ ...(differentModel ? {} : { providerMetadata: metadata(part.metadata) }),
})
if (part.type === "step-start")
assistantMessage.parts.push({
@@ -645,7 +663,7 @@ export namespace MessageV2 {
toolCallId: part.callID,
input: part.state.input,
output,
- ...(differentModel ? {} : { callProviderMetadata: part.metadata }),
+ ...(differentModel ? {} : { callProviderMetadata: metadata(part.metadata) }),
})
}
if (part.state.status === "error")
@@ -655,7 +673,7 @@ export namespace MessageV2 {
toolCallId: part.callID,
input: part.state.input,
errorText: part.state.error,
- ...(differentModel ? {} : { callProviderMetadata: part.metadata }),
+ ...(differentModel ? {} : { callProviderMetadata: metadata(part.metadata) }),
})
// Handle pending/running tool calls to prevent dangling tool_use blocks
// Anthropic/Claude APIs require every tool_use to have a corresponding tool_result
@@ -666,7 +684,7 @@ export namespace MessageV2 {
toolCallId: part.callID,
input: part.state.input,
errorText: "[Tool execution was interrupted]",
- ...(differentModel ? {} : { callProviderMetadata: part.metadata }),
+ ...(differentModel ? {} : { callProviderMetadata: metadata(part.metadata) }),
})
}
Plugins
None
OpenCode version
1.2.10
Steps to reproduce
In a git clone of the opencode repo the following repros the bug for me:
opencode run -m "openrouter/anthropic/claude-opus-4.6" "Read-only investigation. Use at least 10 tool calls (glob, grep, read) across packages
/opencode/src/session and packages/opencode/src/provider. Find every place where reasoning or provider metadata might be rewritten, dropped, trimmed, or remapped. Return a compact table with file, function, and risk. Do not edit files." --thinking true --variant high
Screenshot and/or share link
No response
Operating System
WSL2 on windows 11
Terminal
Windows Terminal
Description
Recently opencode become neigh-on unusable with OpenRouter for me. Most sessions end in a provider error.
It essentially breaks openrouter as provider for me, so its likely something related to my setup, but I can't figure out what.
From the logs the underlying error (using the repro below) is
{ "type": "error", "error": { "type": "invalid_request_error", "message": "messages.1.content.6: `thinking` or `redacted_thinking` blocks in the latest assistant message cannot be modified. These blocks must remain as they were in the original response." }, "request_id": "req_011CYKKYMLyQjjKY8MRfvLHk" }Me and Codex did some digging and it seems that tool Parts have duplicated reasoning attached to them in the session.
The following diff solves the issue for me, but it feels a bit like treating the symptom. If its a good approach, lemme know I can turn it into a PR.
Plugins
None
OpenCode version
1.2.10
Steps to reproduce
In a
git cloneof the opencode repo the following repros the bug for me:Screenshot and/or share link
No response
Operating System
WSL2 on windows 11
Terminal
Windows Terminal