thedotmack/claude-mem · error

manual observation sources cannot be linked to a generation_

Error message

manual observation sources cannot be linked to a generation_job_id

What it means

Thrown by assertGenerationJobMatchesSource when addSource is called with sourceType 'manual' and a non-null generationJobId. Manual sources are user-authored and by design cannot be attributed to an automated generation job, so linking them is rejected before any DB lookup.

Source

Thrown at src/storage/postgres/observations.ts:332

  );
  if (!row) {
    throw new Error('generation_job_id must belong to project_id and team_id');
  }
}

async function assertGenerationJobMatchesSource(
  client: PostgresQueryable,
  input: {
    generationJobId: string;
    projectId: string;
    teamId: string;
    sourceType: ObservationSourceType;
    sourceId: string;
    agentEventId: string | null;
  }
): Promise<void> {
  if (input.sourceType === 'manual') {
    throw new Error('manual observation sources cannot be linked to a generation_job_id');
  }

  const row = await queryOne<{
    id: string;
    source_type: string;
    source_id: string;
    agent_event_id: string | null;
  }>(
    client,
    `
      SELECT id, source_type, source_id, agent_event_id
      FROM observation_generation_jobs
      WHERE id = $1 AND project_id = $2 AND team_id = $3
    `,
    [input.generationJobId, input.projectId, input.teamId]
  );
  if (!row) {
    throw new Error('generation_job_id must belong to project_id and team_id');

View on GitHub (pinned to d768ba3643)

Solutions

  1. For manual sources, omit generationJobId (or pass null/undefined).
  2. Split the flow: manual sources never carry a job id; only agent_event/session_summary/observation_reindex may.

Example fix

// before
await sources.addSource({ observationId, projectId, teamId, sourceType:'manual', sourceId: userId, generationJobId: jobId });
// after
await sources.addSource({ observationId, projectId, teamId, sourceType:'manual', sourceId: userId, generationJobId: null });
Defensive patterns

Strategy: validation

Validate before calling

if (sourceType==='manual' && generationJobId != null) { throw new TypeError('manual sources cannot carry a generationJobId'); }

Type guard

function isManualSourceUnlinked(input){ return input.sourceType!=='manual' || input.generationJobId == null; }

Prevention

When it happens

Trigger: Calling addSource({sourceType:'manual', generationJobId: '...'}). Any non-null generationJobId with a manual source triggers this immediately.

Common situations: UI defaulting generationJobId from context for all source types; importing manual notes while passing a job id; refactor that forgot to clear generationJobId for manual entries.

Related errors


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