{"record":{"id":"71c48f7618505bb2","repo":"different-ai/openwork","slug":"mcp-session-not-found","errorCode":"MCP_SESSION_NOT_FOUND","errorMessage":"MCP_SESSION_NOT_FOUND","messagePattern":"MCP_SESSION_NOT_FOUND","errorType":"error_code","errorClass":null,"httpStatus":404,"severity":"warning","filePath":"ee/apps/den-api/src/capability-sources/external-mcp-diagnostics.ts","lineNumber":899,"sourceCode":"    ...(input.providerRequestId ? { providerRequestId: input.providerRequestId } : {}),\n  })\n}\n\nfunction httpClassification(input: {\n  phase: ExternalMcpDiagnosticPhase\n  status: number\n  hasAuthorization: boolean\n  bearerChallenge: boolean\n  insufficientScope: boolean\n  hasSession: boolean\n  contentType: string\n}): Classification | null {\n  const { phase, status } = input\n  if (status === 404 && input.hasSession) {\n    return {\n      phase: \"CONTINUITY_SESSION\",\n      category: \"mcp_session_expired\",\n      code: \"MCP_SESSION_NOT_FOUND\",\n      retryable: true,\n      actionOwner: \"openwork\",\n      operatorAction: \"Reinitialize the MCP session, then retry the operation once.\",\n    }\n  }\n  if (status === 404 && phase.startsWith(\"MCP_\")) {\n    return {\n      phase: \"HTTP_ROUTING\",\n      category: \"endpoint_not_found\",\n      code: \"MCP_HTTP_404\",\n      retryable: false,\n      actionOwner: \"organization_admin\",\n      operatorAction: \"Verify the complete MCP endpoint path, including any provider tenant or instance prefix.\",\n    }\n  }\n  if ((status === 406 || status === 415) && phase.startsWith(\"MCP_\")) {\n    return {\n      phase: \"MCP_TRANSPORT\",","sourceCodeStart":881,"sourceCodeEnd":917,"githubUrl":"https://github.com/different-ai/openwork/blob/2b7df46e8ae1517d64c896c7793d2d52ec845669/ee/apps/den-api/src/capability-sources/external-mcp-diagnostics.ts#L881-L917","documentation":"MCP_SESSION_NOT_FOUND is produced when an MCP request returns HTTP 404 while the gateway knows a session had been established (input.hasSession). The classifier treats this as a CONTINUITY_SESSION / mcp_session_expired problem: the session id the client is presenting is no longer recognized by the server. Unlike a plain endpoint 404, it is retryable because reinitializing the session should restore operation.","triggerScenarios":"Any request sent during an MCP phase (e.g. MCP_TOOL_EXECUTION or MCP_TOOL_DISCOVERY) with a previously negotiated Mcp-Session-Id header where the server responds 404, and hasSession is true. Typical call: client.callTool(...) on a streamable-HTTP MCP connection after the server dropped the session.","commonSituations":"Server restart or redeploy between calls invalidating in-memory sessions; server-side session TTL/timeout expiring during long pauses; load balancer routing to a replica without the session state; provider upgraded and rotated session stores.","solutions":["Reinitialize the MCP session (new initialize handshake to obtain a fresh Mcp-Session-Id).","Retry the failed operation once with the new session, as the diagnostic prescribes.","If it recurs, shorten the interval between calls or enable session keep-alive; verify the load balancer is not splitting session traffic."],"exampleFix":"// before: reusing a stale session id\nconst res = await fetch(mcpUrl, { headers: { 'Mcp-Session-Id': staleId, ... } })\n// after: reinitialize and reuse the new session id\nconst init = await initialize(mcpUrl)\nconst res = await fetch(mcpUrl, { headers: { 'Mcp-Session-Id': init.sessionId, ... } })","handlingStrategy":"retry","validationCode":"// check session freshness before reuse\nasync function sessionValid(url: string, sessionId: string): Promise<boolean> {\n  const res = await fetch(url, { method: 'GET', headers: { 'Mcp-Session-Id': sessionId } })\n  return res.status !== 404\n}","typeGuard":"function isSessionExpired(d: { code: string; category?: string }): boolean {\n  return d.code === 'MCP_SESSION_NOT_FOUND' || d.category === 'mcp_session_expired'\n}","tryCatchPattern":"try {\n  return await withSession(sessionId, () => client.callTool(req))\n} catch (e) {\n  if (isSessionExpired(e.diagnostic)) {\n    const fresh = await initialize(mcpUrl) // one reinitialize + single retry\n    return await withSession(fresh.sessionId, () => client.callTool(req))\n  }\n  throw e\n}","preventionTips":["Send periodic keep-alive/ping requests to keep long-lived MCP sessions from expiring.","Reinitialize the session after any server restart or redeploy of the provider.","Avoid caching Mcp-Session-Id across processes or longer than the provider's session TTL."],"tags":["mcp","session","http-404","retryable","expired"],"backgroundTag":"mcp-session-expired","analyzedSha":"2b7df46e8ae1517d64c896c7793d2d52ec845669","analyzedAt":"2026-09-01T07:59:23.713Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-08T10:18:20.063Z"}