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
MCP streamable-HTTP transport: 'Session not found' from server permanently breaks tool calls (no auto-reconnect) #25137
When a remote MCP server invalidates a streamable-HTTP session (server restart, idle timeout, periodic rotation, etc.), opencode keeps sending the same stale mcp-session-id. The server returns:
Streamable HTTP error: Error POSTing to endpoint: {"error":"Session not found"}
Once this happens, every subsequent tool call against that MCP server fails with the same error for the rest of the opencode session. The only fix is opencode mcp logout && opencode mcp auth and a process restart. There's no retry, no reconnect, no onclose handler.
This is in the same family as #17099 (no retry / reconnect for listTools() failures) but on a different code path: client.callTool() in convertMcpTool (packages/opencode/src/mcp/index.ts). #15209 reported essentially the same bug back in February but was auto-closed for not following the issue template — reopening here properly.
Steps to reproduce
Configure a remote streamable-HTTP MCP server.
Use it normally — agent calls a few tools successfully.
Restart that MCP server (or wait for any server-side session invalidation).
Have the agent call any tool on that server again.
→ Streamable HTTP error: Error POSTing to endpoint: {"error":"Session not found"}. All subsequent calls to that server fail until opencode is restarted.
OpenCode version
1.14.30
Operating System
macOS 14 (Sequoia)
Expected
When the server reports the session is gone, opencode rebuilds the transport and replays the call once. If the retry also fails, surface the error normally.
Since you've already referenced #17099 and #15209 in your report, the maintainers may want to consolidate these under one of those issues or confirm this as a distinct sub-case (streamable-HTTP callTool() path vs. listTools() path in #17099).
The fix in #32088 only triggers session recovery on HTTP 404 (Session not found). However, not all MCP servers signal an expired session with 404.
The Atlassian/Jira MCP server (server: uvicorn, Atlassian MCP v1.12.4) used in our enterprise setup responds with HTTP 400 when the session has expired. Reproduced against the live server by sending a POST tools/list with a stale mcp-session-id:
HTTP/1.1 400 Bad Request
server: uvicorn
content-length: 41
Bad Request: No valid session ID provided
And the initial handshake (no session yet) returns a structured JSON-RPC error:
Because the recovery logic only reinitializes on 404, our sessions never auto-recover: after the server-side idle timeout, every subsequent tool call fails with Bad Request: No valid session ID provided until opencode is fully restarted. This happens reliably every ~15-30 min of inactivity.
Would it be possible to extend the recovery trigger to also cover a 400 carrying a session-id error — e.g. response body containing No valid session ID / Missing session ID, or JSON-RPC code -32600 with session in the message? That would make the recovery work for spec-compliant-ish servers that use 400 instead of 404 for expired/missing sessions.
Activity
github-actions commentedon Apr 30, 2026
This issue might be a duplicate of existing issues. Please check:
mcp/index.ts, same symptom of permanent failure until restart)Since you've already referenced #17099 and #15209 in your report, the maintainers may want to consolidate these under one of those issues or confirm this as a distinct sub-case (streamable-HTTP
callTool()path vs.listTools()path in #17099).ainhoacr commentedon Jun 18, 2026
The fix in #32088 only triggers session recovery on HTTP 404 (
Session not found). However, not all MCP servers signal an expired session with 404.The Atlassian/Jira MCP server (server:
uvicorn,Atlassian MCP v1.12.4) used in our enterprise setup responds with HTTP 400 when the session has expired. Reproduced against the live server by sending aPOST tools/listwith a stalemcp-session-id:And the initial handshake (no session yet) returns a structured JSON-RPC error:
{"jsonrpc":"2.0","id":"server-error","error":{"code":-32600,"message":"Bad Request: Missing session ID"}}Because the recovery logic only reinitializes on 404, our sessions never auto-recover: after the server-side idle timeout, every subsequent tool call fails with
Bad Request: No valid session ID provideduntil opencode is fully restarted. This happens reliably every ~15-30 min of inactivity.Would it be possible to extend the recovery trigger to also cover a 400 carrying a session-id error — e.g. response body containing
No valid session ID/Missing session ID, or JSON-RPC code-32600withsessionin the message? That would make the recovery work for spec-compliant-ish servers that use 400 instead of 404 for expired/missing sessions.Environment:
type: remote)A delegate, handoff or page call runs once per its harness's key: a r…