{"record":{"id":"7b9f2507124fff5a","repo":"thedotmack/claude-mem","slug":"generation-job-id-agent-event-id-must-match-observ","errorCode":null,"errorMessage":"generation_job_id agent_event_id must match observation source","messagePattern":"generation_job_id agent_event_id must match observation source","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"src/storage/postgres/observations.ts","lineNumber":356,"sourceCode":"    source_id: string;\n    agent_event_id: string | null;\n  }>(\n    client,\n    `\n      SELECT id, source_type, source_id, agent_event_id\n      FROM observation_generation_jobs\n      WHERE id = $1 AND project_id = $2 AND team_id = $3\n    `,\n    [input.generationJobId, input.projectId, input.teamId]\n  );\n  if (!row) {\n    throw new Error('generation_job_id must belong to project_id and team_id');\n  }\n  if (row.source_type !== input.sourceType || row.source_id !== input.sourceId) {\n    throw new Error('generation_job_id source model must match observation source');\n  }\n  if (input.sourceType === 'agent_event' && row.agent_event_id !== input.agentEventId) {\n    throw new Error('generation_job_id agent_event_id must match observation source');\n  }\n}\n\nasync function assertAgentEventOwnership(\n  client: PostgresQueryable,\n  agentEventId: string,\n  projectId: string,\n  teamId: string\n): Promise<void> {\n  const row = await queryOne<{ id: string }>(\n    client,\n    'SELECT id FROM agent_events WHERE id = $1 AND project_id = $2 AND team_id = $3',\n    [agentEventId, projectId, teamId]\n  );\n  if (!row) {\n    throw new Error('agent_event_id must belong to project_id and team_id');\n  }\n}","sourceCodeStart":338,"sourceCodeEnd":374,"githubUrl":"https://github.com/thedotmack/claude-mem/blob/d768ba364302d12b76e69e4f021f0bb1d2d50ed6/src/storage/postgres/observations.ts#L338-L374","documentation":"Thrown by assertGenerationJobMatchesSource for agent_event sources after the source_type/source_id match. It additionally checks that the job's agent_event_id equals the observation source's agentEventId. Even when both point to the same event, a divergent agent_event_id on either side rejects the link.","triggerScenarios":"addSource with sourceType 'agent_event', a generationJobId, where the job's stored agent_event_id != the resolved agentEventId (agentEventId ?? sourceId) of the observation source.","commonSituations":"Job created from one event but the observation source references a different event id; passing sourceId without agentEventId while the job stored a distinct agent_event_id.","solutions":["Ensure agentEventId passed to addSource equals the job's agent_event_id (read it from the job).","For agent_event, set sourceId === agentEventId === job.agentEventId.","Recreate the job from the correct event if they truly differ."],"exampleFix":"// before\nawait sources.addSource({ observationId, projectId, teamId, sourceType:'agent_event', sourceId: eventId, agentEventId: otherId, generationJobId });\n// after\nconst job = await jobs.getByIdForScope({ id: generationJobId, projectId, teamId });\nawait sources.addSource({ observationId, projectId, teamId, sourceType:'agent_event', sourceId: job.agentEventId!, agentEventId: job.agentEventId, generationJobId: job.id });","handlingStrategy":"validation","validationCode":"const job = await jobs.getByIdForScope({ id: generationJobId, projectId, teamId });\nif (sourceType==='agent_event' && job.agentEventId !== (agentEventId ?? sourceId)) throw new Error('agent_event_id mismatch with job');","typeGuard":"function agentEventJobConsistent(job, input){ return job.sourceType!=='agent_event' || job.agentEventId === (input.agentEventId ?? input.sourceId); }","tryCatchPattern":null,"preventionTips":["For agent_event jobs, sourceId, agentEventId, and job.agentEventId must all be equal."],"tags":["postgres","validation","observations","invariant"],"backgroundTag":null,"analyzedSha":"d768ba364302d12b76e69e4f021f0bb1d2d50ed6","analyzedAt":"2026-08-12T23:52:55.241Z","schemaVersion":2},"datasetVersion":"2026-08-13T04:17:16.726Z"}