thedotmack/claude-mem · error
generation_job_id agent_event_id must match observation sour
Error message
generation_job_id agent_event_id must match observation source
What it means
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.
Source
Thrown at src/storage/postgres/observations.ts:356
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');
}
if (row.source_type !== input.sourceType || row.source_id !== input.sourceId) {
throw new Error('generation_job_id source model must match observation source');
}
if (input.sourceType === 'agent_event' && row.agent_event_id !== input.agentEventId) {
throw new Error('generation_job_id agent_event_id must match observation source');
}
}
async function assertAgentEventOwnership(
client: PostgresQueryable,
agentEventId: string,
projectId: string,
teamId: string
): Promise<void> {
const row = await queryOne<{ id: string }>(
client,
'SELECT id FROM agent_events WHERE id = $1 AND project_id = $2 AND team_id = $3',
[agentEventId, projectId, teamId]
);
if (!row) {
throw new Error('agent_event_id must belong to project_id and team_id');
}
}View on GitHub (pinned to d768ba3643)
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.
Example fix
// before
await sources.addSource({ observationId, projectId, teamId, sourceType:'agent_event', sourceId: eventId, agentEventId: otherId, generationJobId });
// after
const job = await jobs.getByIdForScope({ id: generationJobId, projectId, teamId });
await sources.addSource({ observationId, projectId, teamId, sourceType:'agent_event', sourceId: job.agentEventId!, agentEventId: job.agentEventId, generationJobId: job.id }); Defensive patterns
Strategy: validation
Validate before calling
const job = await jobs.getByIdForScope({ id: generationJobId, projectId, teamId });
if (sourceType==='agent_event' && job.agentEventId !== (agentEventId ?? sourceId)) throw new Error('agent_event_id mismatch with job'); Type guard
function agentEventJobConsistent(job, input){ return job.sourceType!=='agent_event' || job.agentEventId === (input.agentEventId ?? input.sourceId); } Prevention
- For agent_event jobs, sourceId, agentEventId, and job.agentEventId must all be equal.
When it happens
Trigger: addSource with sourceType 'agent_event', a generationJobId, where the job's stored agent_event_id != the resolved agentEventId (agentEventId ?? sourceId) of the observation source.
Common situations: 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.
Related errors
- agent_event source_id must equal agent_event_id
- manual observation sources cannot be linked to a generation_
- generation_job_id source model must match observation source
- observation_id does not exist
- generation_job_id must belong to project_id and team_id
AI-assisted analysis of thedotmack/claude-mem@d768ba3643 (2026-08-12).
Data as JSON: /api/errors/7b9f2507124fff5a.
Report an issue: GitHub.