thedotmack/claude-mem · error
observation_id does not exist
Error message
observation_id does not exist
What it means
Thrown by PostgresObservationSourcesRepository.addSource. It first checks that the target observation exists within (observationId, projectId, teamId). If no row is returned, the observation you are trying to attach a source to is not in scope (missing, wrong tenant, or deleted).
Source
Thrown at src/storage/postgres/observations.ts:219
async addSource(input: {
id?: string;
observationId: string;
projectId: string;
teamId: string;
sourceType: ObservationSourceType;
sourceId: string;
agentEventId?: string | null;
generationJobId?: string | null;
metadata?: JsonObject;
}): Promise<PostgresObservationSource> {
const observation = await queryOne<{ id: string }>(
this.client,
'SELECT id FROM observations WHERE id = $1 AND project_id = $2 AND team_id = $3',
[input.observationId, input.projectId, input.teamId]
);
if (!observation) {
throw new Error('observation_id does not exist');
}
const agentEventId = input.sourceType === 'agent_event'
? input.agentEventId ?? input.sourceId
: null;
if (input.sourceType === 'agent_event') {
if (agentEventId !== input.sourceId) {
throw new Error('agent_event source_id must equal agent_event_id');
}
await assertAgentEventOwnership(this.client, input.sourceId, input.projectId, input.teamId);
} else if (input.sourceType === 'session_summary' && !input.generationJobId) {
await assertSessionOwnership(this.client, input.sourceId, input.projectId, input.teamId);
} else if (input.sourceType === 'observation_reindex' && !input.generationJobId) {
await assertObservationOwnership(this.client, input.sourceId, input.projectId, input.teamId);
}
if (input.generationJobId) {
await assertGenerationJobMatchesSource(this.client, {View on GitHub (pinned to d768ba3643)
Solutions
- Create the observation first (repository.create on PostgresObservationRepository) and use its returned id.
- Resolve the observation via getByIdForScope before calling addSource; fail fast with a clearer message.
- Confirm projectId/teamId match the observation's owner tenant.
Example fix
// before
await sources.addSource({ observationId, projectId, teamId, sourceType:'agent_event', sourceId: eventId });
// after
const obs = await observations.create({ projectId, teamId, content, ... });
await sources.addSource({ observationId: obs.id, projectId, teamId, sourceType:'agent_event', sourceId: eventId }); Defensive patterns
Strategy: validation
Validate before calling
const obs = await observations.getByIdForScope({ id: observationId, projectId, teamId });
if (!obs) throw new Error(`observation ${observationId} not in scope`); Prevention
- Always create the parent observation before attaching sources.
- Keep observation and source creation in the same transaction.
When it happens
Trigger: Calling addSource() with an observationId that is not present in observations for the supplied project/team. The observation may belong to another tenant or may have never been created.
Common situations: Adding a source before creating the observation; cross-tenant id reuse; observation deleted by a cleanup job; using a source id instead of an observation id.
Related errors
- generation_job_id must belong to project_id and team_id
- agent_event_id must belong to project_id and team_id
- observation_reindex source_id must belong to project_id and
- server_session_id must match the agent_event server_session_
- observation_reindex source_id must belong to project_id and
AI-assisted analysis of thedotmack/claude-mem@d768ba3643 (2026-08-12).
Data as JSON: /api/errors/4da2853bafb5ad54.
Report an issue: GitHub.