{"record":{"id":"75eb10cd8e92e17d","repo":"thedotmack/claude-mem","slug":"internal-error","errorCode":null,"errorMessage":"internal_error","messagePattern":"internal_error","errorType":"http","errorClass":null,"httpStatus":500,"severity":"error","filePath":"src/server/compat/SessionsObservationsAdapter.ts","lineNumber":94,"sourceCode":"      if (!projectId) {\n        // Compat mode requires a project-scoped key — the legacy payload does\n        // not carry a Server beta projectId, so without scope we cannot place\n        // the row in a tenant-scoped table.\n        res.status(400).json({\n          error: 'BadRequest',\n          message: 'Legacy /api/sessions/observations requires a project-scoped API key',\n        });\n        return;\n      }\n\n      try {\n        await this.ingestCompatObservation(req, res, parsed.data, teamId, projectId);\n      } catch (error) {\n        logger.error('SYSTEM', 'compat observations adapter failed', {\n          error: error instanceof Error ? error.message : String(error),\n          contentSessionId: parsed.data.contentSessionId,\n        });\n        res.status(500).json({ stored: false, reason: 'internal_error' });\n      }\n    }));\n  }\n\n  // Body of the legacy observations route — translates the legacy payload\n  // into a Server beta agent_event and delegates to IngestEventsService.\n  private async ingestCompatObservation(\n    req: Request,\n    res: Response,\n    data: z.infer<typeof observationsSchema>,\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    );","sourceCodeStart":76,"sourceCodeEnd":112,"githubUrl":"https://github.com/thedotmack/claude-mem/blob/d8bc9755e74915e5c3b999181e10a67c889bce2a/src/server/compat/SessionsObservationsAdapter.ts#L76-L112","documentation":"The compat observations adapter wraps ingestion in a try/catch and responds with HTTP 500 { stored:false, reason:'internal_error' } for any unexpected failure while translating the legacy payload into a Server beta agent_event and delegating to IngestEventsService. It is a generic catch-all; the real cause is only in the server logs under 'compat observations adapter failed'.","triggerScenarios":"Any exception thrown inside ingestCompatObservation — e.g. database write failure, IngestEventsService rejection, schema/tenant lookup error — after the payload has passed validation.","commonSituations":"Database outage or migration drift when inserting the agent_event row; null/undefined fields in the legacy payload that hit unexpected code paths; bugs introduced during compat-layer refactors.","solutions":["Check server logs for the 'compat observations adapter failed' entry to find the underlying exception","Retry the request after confirming the database is reachable and migrations are current","Inspect the legacy payload for unexpected nulls (contentSessionId etc.) and fix the client","Add explicit handling/mapping for the underlying error class in the adapter"],"exampleFix":"// server log\n// before: { stored:false, reason:'internal_error' } with no clue\n// after: logger.error includes error.stack and parsed payload for diagnosis\nlogger.error('SYSTEM', 'compat observations adapter failed', { error: err.message, stack: err.stack, payload: parsed.data });","handlingStrategy":"retry","validationCode":"// client-side pre-check\nif (!payload.contentSessionId) throw new Error('contentSessionId is required before ingest');","typeGuard":"const hasSessionId = (p) => typeof p?.contentSessionId === 'string' && p.contentSessionId.length > 0;","tryCatchPattern":"// client: retry transient 500s, surface persistent ones\nif (res.status === 500 && body.reason === 'internal_error') {\n  if (attempt < 3) return retryWithBackoff(attempt + 1);\n  throw new Error(`Ingest failed persistently: ${await res.text()}`);\n}","preventionTips":["Monitor server logs for 'compat observations adapter failed' with alerting","Keep database migrations current before deploying the server","Include error.stack in the adapter's log payload for faster diagnosis","Add integration tests covering the legacy payload -> agent_event translation"],"tags":["http","internal-error","ingestion","compat"],"backgroundTag":"internal-invariant-violation","analyzedSha":"d8bc9755e74915e5c3b999181e10a67c889bce2a","analyzedAt":"2026-09-17T16:40:26.182Z","contentChangedAt":"2026-09-17T16:40:26.182Z","schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}