thedotmack/claude-mem · error · Error

ingestObservation failed: ${result.reason}

Error message

ingestObservation failed: ${result.reason}

What it means

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.

Source

Thrown at src/services/transcripts/processor.ts:258

    }
  }

  private async sendObservation(session: SessionState, fields: Record<string, unknown>): Promise<void> {
    const toolName = typeof fields.toolName === 'string' ? fields.toolName : undefined;
    if (!toolName) return;

    const result = await ingestObservation({
      contentSessionId: session.sessionId,
      cwd: session.cwd ?? process.cwd(),
      toolName,
      toolInput: this.maybeParseJson(fields.toolInput),
      toolResponse: this.maybeParseJson(fields.toolResponse),
      platformSource: session.platformSource,
      toolUseId: typeof fields.toolUseId === 'string' ? fields.toolUseId : undefined,
    });

    if (!result.ok) {
      throw new Error(`ingestObservation failed: ${result.reason}`);
    }
  }

  private async sendFileEdit(session: SessionState, fields: Record<string, unknown>): Promise<void> {
    const filePath = typeof fields.filePath === 'string' ? fields.filePath : undefined;
    if (!filePath) return;

    await fileEditHandler.execute({
      sessionId: session.sessionId,
      cwd: session.cwd ?? process.cwd(),
      filePath,
      edits: Array.isArray(fields.edits) ? fields.edits : undefined,
      platform: session.platformSource
    });
  }

  private maybeParseJson(value: unknown): unknown {
    if (typeof value !== 'string') return value;

View on GitHub (pinned to d768ba3643)

Solutions

  1. Read result.reason embedded in the message — it is the underlying cause (DB error, constraint, privacy).
  2. If the reason is a DB/constraint error, inspect sqlite for the sdk_sessions row and the failing statement.
  3. Ensure the worker HTTP context is initialized (requireContext() resolved) before transcript processing runs.
  4. If the reason is privacy-related, review PrivacyCheckValidator configuration and the offending prompt/tool input.
  5. Wrap sendObservation in a try-catch to log+continue so one bad observation doesn't halt the whole transcript ingest loop.

Example fix

// before: await this.sendObservation(session, fields); // throws, halts loop
// after:  try { await this.sendObservation(session, fields); }
//         catch (e) { logger.error('TRANSCRIPT', 'observation ingest failed', { sessionId: session.sessionId }, e instanceof Error ? e : undefined); }
Defensive patterns

Strategy: try-catch

Validate before calling

// Pre-flight: ensure the worker HTTP context is ready and the session is resolvable
import { requireContext } from '../worker/http/shared';
function preflight(contentSessionId: string): void {
  const { sessionManager, dbManager } = requireContext(); // throws if not initialized
  if (!contentSessionId) throw new Error('contentSessionId required for observation');
}

Try / catch

try { await this.sendObservation(session, fields); }
catch (e) {
  if (e instanceof Error && e.message.startsWith('ingestObservation failed')) {
    // log reason embedded in message; do not halt the transcript loop
    logger.error('TRANSCRIPT', e.message, { sessionId: session.sessionId }, e);
    return;
  }
  throw e;
}

Prevention

When it happens

Trigger: 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.

Common situations: 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.

Related errors


AI-assisted analysis of thedotmack/claude-mem@d768ba3643 (2026-08-12). Data as JSON: /api/errors/a605f3fe69ee83d9. Report an issue: GitHub.