{"record":{"id":"77ccb09d056927d1","repo":"eyaltoledano/claude-task-master","slug":"session-error","errorCode":"SESSION_ERROR","errorMessage":"${message}","messagePattern":"\\$\\{message\\}","errorType":"error_code","errorClass":"MCPSessionError","httpStatus":null,"severity":"error","filePath":"mcp-server/src/custom-sdk/errors.js","lineNumber":59,"sourceCode":"/**\n * Map MCP errors to AI SDK compatible error types\n * @param {Error} error - Original error\n * @returns {Error} Mapped error\n */\nexport function mapMCPError(error) {\n\t// If already an MCP error, return as-is\n\tif (error instanceof MCPError) {\n\t\treturn error;\n\t}\n\n\tconst message = error.message || 'Unknown MCP error';\n\tconst originalError = error;\n\n\t// Map common error patterns\n\tif (message.includes('session') || message.includes('connection')) {\n\t\treturn new MCPSessionError(message, {\n\t\t\tcause: originalError,\n\t\t\tcode: 'SESSION_ERROR'\n\t\t});\n\t}\n\n\tif (message.includes('sampling') || message.includes('timeout')) {\n\t\treturn new MCPSamplingError(message, {\n\t\t\tcause: originalError,\n\t\t\tcode: 'SAMPLING_ERROR'\n\t\t});\n\t}\n\n\tif (message.includes('capabilities') || message.includes('not supported')) {\n\t\treturn new MCPSessionError(message, {\n\t\t\tcause: originalError,\n\t\t\tcode: 'CAPABILITY_ERROR'\n\t\t});\n\t}\n\n\t// Default to generic MCP error","sourceCodeStart":41,"sourceCodeEnd":77,"githubUrl":"https://github.com/eyaltoledano/claude-task-master/blob/c0c98d367c55296bfe69e65680625b6db437af02/mcp-server/src/custom-sdk/errors.js#L41-L77","documentation":"mapMCPError classifies arbitrary thrown errors by substring-matching their message. If the message contains 'session' or 'connection', it is re-wrapped as MCPSessionError with code SESSION_ERROR, preserving the original as cause. isRetryableError treats SESSION_ERROR as non-retryable.","triggerScenarios":"doGenerate/doGenerateObject/doStream call mapMCPError on any error whose message mentions the MCP session or connection — e.g. server disconnected mid-request, session expired, transport closed.","commonSituations":"MCP server process crashed or was restarted; stdio/HTTP transport dropped; long-lived session idle-timed out; load balancer cut a persistent connection.","solutions":["Reconnect to the MCP server and create a fresh session, then retry the request","Check that the MCP server process is running and the transport config (stdio command / URL) is correct","Inspect error.cause for the underlying transport failure","Do not blind-retry: SESSION_ERROR is classified as non-retryable without a new session"],"exampleFix":"// before\nconst res = await doGenerate(prompt); // throws after server restart\n// after\ntry {\n  const res = await doGenerate(prompt);\n} catch (e) {\n  if (e instanceof MCPSessionError) { await reconnect(); return doGenerate(prompt); }\n  throw e;\n}","handlingStrategy":"try-catch","validationCode":"function checkServerConnection(client) {\n  return client.isConnected?.() ?? true; // verify transport before expensive calls\n}","typeGuard":"function isMCPSessionError(e: unknown): e is MCPSessionError {\n  return e instanceof MCPSessionError || (typeof e === 'object' && e !== null && (e as any).code === 'SESSION_ERROR');\n}","tryCatchPattern":"try {\n  await doGenerate(prompt);\n} catch (e) {\n  if (isMCPSessionError(e)) {\n    await reconnectAndCreateSession();\n    return doGenerate(prompt); // retry only after fresh session\n  }\n  throw e;\n}","preventionTips":["Monitor MCP server process health and restart on exit","Configure transport keepalives/timeouts to avoid idle session drops","Never blind-retry SESSION_ERROR without re-establishing the session","Inspect error.cause to distinguish transport vs. protocol failures"],"tags":["mcp","session","connection"],"backgroundTag":"mcp-session-disconnected","analyzedSha":"c0c98d367c55296bfe69e65680625b6db437af02","analyzedAt":"2026-08-29T02:56:26.071Z","schemaVersion":2},"datasetVersion":"2026-08-29T07:17:48.351Z"}