{"record":{"id":"662294cf164f2601","repo":"thedotmack/claude-mem","slug":"internal-error-662294","errorCode":"internal_error","errorMessage":"internal_error","messagePattern":"internal_error","errorType":"http","errorClass":null,"httpStatus":500,"severity":"error","filePath":"src/server/compat/SessionsSummarizeAdapter.ts","lineNumber":85,"sourceCode":"        return;\n      }\n\n      // Subagent contexts in legacy code emit summarize calls but the worker\n      // skipped them. We preserve the legacy semantics so existing clients\n      // see the same response shape.\n      if (parsed.data.agentId) {\n        res.json({ status: 'skipped', reason: 'subagent_context' });\n        return;\n      }\n\n      try {\n        await this.summarizeSession(req, res, parsed.data, teamId, projectId);\n      } catch (error) {\n        logger.error('SYSTEM', 'compat summarize adapter failed', {\n          error: error instanceof Error ? error.message : String(error),\n          contentSessionId: parsed.data.contentSessionId,\n        });\n        res.status(500).json({ status: 'error', reason: 'internal_error' });\n      }\n    }));\n  }\n\n  private async summarizeSession(\n    req: Request,\n    res: Response,\n    data: z.infer<typeof summarizeSchema>,\n    teamId: string,\n    projectId: string,\n  ): Promise<void> {\n    const platformSource = normalizePlatformSource(\n      typeof data.platformSource === 'string'\n        ? data.platformSource\n        : DEFAULT_PLATFORM_SOURCE,\n    );\n    const session = await resolveServerSession({\n      pool: this.options.pool,","sourceCodeStart":67,"sourceCodeEnd":103,"githubUrl":"https://github.com/thedotmack/claude-mem/blob/e2d1df569a8f04075d40e92461128ece7cf04c82/src/server/compat/SessionsSummarizeAdapter.ts#L67-L103","documentation":"Catch-all 500 from the compat summarize adapter: any exception thrown by summarizeSession (database failures, session lookup errors other than not-found, endSession faults) is logged as 'compat summarize adapter failed' with the contentSessionId, then surfaced as { status: 'error', reason: 'internal_error' }. The response deliberately hides the cause; the server log holds it.","triggerScenarios":"Postgres/SQLite connectivity drop mid-request during endSession; the session row exists at lookup but disappears before the end/outbox transaction; an enqueue failure inside endSession; any unexpected throw in normalizePlatformSource or downstream persistence.","commonSituations":"DB restart or failover while legacy Claude Code clients flush summarize calls; migrations that rename columns the adapter touches; connection pool exhaustion under load so endSession throws instead of timing out cleanly.","solutions":["Check server logs for 'compat summarize adapter failed' — the error message and contentSessionId identify the real cause.","Verify database connectivity and pool health; most instances are transient storage faults.","Confirm the session identified by contentSessionId exists and belongs to the key's team/project.","If it recurs on one session, inspect that session's rows for constraint or state corruption; retry once after fixing."],"exampleFix":null,"handlingStrategy":"try-catch","validationCode":null,"typeGuard":"interface Compat500 { status: string; reason: string }\nfunction isInternalError(body: unknown): body is Compat500 {\n  return typeof body === 'object' && body !== null &&\n    (body as Compat500).status === 'error' && (body as Compat500).reason === 'internal_error';\n}","tryCatchPattern":"try {\n  const res = await fetch(`${base}/api/sessions/summarize`, opts);\n  if (res.status === 500) {\n    const body = await res.json().catch(() => null);\n    if (isInternalError(body)) {\n      logger.warn('summarize internal_error', { contentSessionId });\n      await sleep(2000);\n      return retryOnce(); // transient storage faults are common\n    }\n  }\n  return res;\n} catch (e) {\n  throw new SummarizeTransportError(String(e));\n}","preventionTips":["Retry 500s once with backoff; treat a second consecutive failure as an outage.","Always log contentSessionId when this fires so server logs can be correlated.","Monitor DB pool health — most of these come from storage pressure."],"tags":["http-500","internal-error","claude-code-compat","catch-all","logging"],"backgroundTag":"internal-server-error","analyzedSha":"e2d1df569a8f04075d40e92461128ece7cf04c82","analyzedAt":"2026-08-20T23:58:13.836Z","schemaVersion":2},"datasetVersion":"2026-08-29T17:17:51.833Z"}