{"record":{"id":"a605f3fe69ee83d9","repo":"thedotmack/claude-mem","slug":"ingestobservation-failed-result-reason","errorCode":null,"errorMessage":"ingestObservation failed: ${result.reason}","messagePattern":"ingestObservation failed: (.+?)","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"src/services/transcripts/processor.ts","lineNumber":258,"sourceCode":"    }\n  }\n\n  private async sendObservation(session: SessionState, fields: Record<string, unknown>): Promise<void> {\n    const toolName = typeof fields.toolName === 'string' ? fields.toolName : undefined;\n    if (!toolName) return;\n\n    const result = await ingestObservation({\n      contentSessionId: session.sessionId,\n      cwd: session.cwd ?? process.cwd(),\n      toolName,\n      toolInput: this.maybeParseJson(fields.toolInput),\n      toolResponse: this.maybeParseJson(fields.toolResponse),\n      platformSource: session.platformSource,\n      toolUseId: typeof fields.toolUseId === 'string' ? fields.toolUseId : undefined,\n    });\n\n    if (!result.ok) {\n      throw new Error(`ingestObservation failed: ${result.reason}`);\n    }\n  }\n\n  private async sendFileEdit(session: SessionState, fields: Record<string, unknown>): Promise<void> {\n    const filePath = typeof fields.filePath === 'string' ? fields.filePath : undefined;\n    if (!filePath) return;\n\n    await fileEditHandler.execute({\n      sessionId: session.sessionId,\n      cwd: session.cwd ?? process.cwd(),\n      filePath,\n      edits: Array.isArray(fields.edits) ? fields.edits : undefined,\n      platform: session.platformSource\n    });\n  }\n\n  private maybeParseJson(value: unknown): unknown {\n    if (typeof value !== 'string') return value;","sourceCodeStart":240,"sourceCodeEnd":276,"githubUrl":"https://github.com/thedotmack/claude-mem/blob/d768ba364302d12b76e69e4f021f0bb1d2d50ed6/src/services/transcripts/processor.ts#L240-L276","documentation":"Thrown by TranscriptProcessor.sendObservation when ingestObservation returns `{ ok: false, reason }`. ingestObservation performs session resolution, privacy checks, and message insertion; on any internal failure it returns ok:false with a reason string rather than throwing. This error re-surfaces that failure as an exception so the transcript loop sees it.","triggerScenarios":"sendObservation awaits ingestObservation({ contentSessionId, cwd, toolName, toolInput, toolResponse, platformSource, toolUseId }); if result.ok is false, throws with result.reason. The reason typically comes from the session-resolution try/catch inside ingestObservation (e.g. createSDKSession/getPromptNumberFromUserPrompts threw) or a privacy/validation failure path.","commonSituations":"Database error during sdk_session creation, a uniqueness/constraint violation on the session, privacy check returning a hard failure, missing required context (ensureContext not ready), or the worker HTTP shared module not initialized (requireContext() failing). The reason string is the key diagnostic.","solutions":["Read result.reason embedded in the message — it is the underlying cause (DB error, constraint, privacy).","If the reason is a DB/constraint error, inspect sqlite for the sdk_sessions row and the failing statement.","Ensure the worker HTTP context is initialized (requireContext() resolved) before transcript processing runs.","If the reason is privacy-related, review PrivacyCheckValidator configuration and the offending prompt/tool input.","Wrap sendObservation in a try-catch to log+continue so one bad observation doesn't halt the whole transcript ingest loop."],"exampleFix":"// before: await this.sendObservation(session, fields); // throws, halts loop\n// after:  try { await this.sendObservation(session, fields); }\n//         catch (e) { logger.error('TRANSCRIPT', 'observation ingest failed', { sessionId: session.sessionId }, e instanceof Error ? e : undefined); }","handlingStrategy":"try-catch","validationCode":"// Pre-flight: ensure the worker HTTP context is ready and the session is resolvable\nimport { requireContext } from '../worker/http/shared';\nfunction preflight(contentSessionId: string): void {\n  const { sessionManager, dbManager } = requireContext(); // throws if not initialized\n  if (!contentSessionId) throw new Error('contentSessionId required for observation');\n}","typeGuard":null,"tryCatchPattern":"try { await this.sendObservation(session, fields); }\ncatch (e) {\n  if (e instanceof Error && e.message.startsWith('ingestObservation failed')) {\n    // log reason embedded in message; do not halt the transcript loop\n    logger.error('TRANSCRIPT', e.message, { sessionId: session.sessionId }, e);\n    return;\n  }\n  throw e;\n}","preventionTips":["Initialize the worker HTTP context (requireContext) before transcript processing starts.","Surface result.reason to logs even on ok:true status:'skipped' to spot silent drops.","Isolate per-observation failures so one bad ingest doesn't stop the whole session."],"tags":["transcripts","ingest","observation","database","worker"],"backgroundTag":null,"analyzedSha":"d768ba364302d12b76e69e4f021f0bb1d2d50ed6","analyzedAt":"2026-08-12T23:52:55.241Z","schemaVersion":2},"datasetVersion":"2026-08-13T04:17:16.726Z"}