{"record":{"id":"bbc4cf804be63a5f","repo":"thedotmack/claude-mem","slug":"agent-event-source-id-must-equal-agent-event-id","errorCode":null,"errorMessage":"agent_event source_id must equal agent_event_id","messagePattern":"agent_event source_id must equal agent_event_id","errorType":"validation","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"src/storage/postgres/observations.ts","lineNumber":228,"sourceCode":"    generationJobId?: string | null;\n    metadata?: JsonObject;\n  }): Promise<PostgresObservationSource> {\n    const observation = await queryOne<{ id: string }>(\n      this.client,\n      'SELECT id FROM observations WHERE id = $1 AND project_id = $2 AND team_id = $3',\n      [input.observationId, input.projectId, input.teamId]\n    );\n    if (!observation) {\n      throw new Error('observation_id does not exist');\n    }\n\n    const agentEventId = input.sourceType === 'agent_event'\n      ? input.agentEventId ?? input.sourceId\n      : null;\n\n    if (input.sourceType === 'agent_event') {\n      if (agentEventId !== input.sourceId) {\n        throw new Error('agent_event source_id must equal agent_event_id');\n      }\n      await assertAgentEventOwnership(this.client, input.sourceId, input.projectId, input.teamId);\n    } else if (input.sourceType === 'session_summary' && !input.generationJobId) {\n      await assertSessionOwnership(this.client, input.sourceId, input.projectId, input.teamId);\n    } else if (input.sourceType === 'observation_reindex' && !input.generationJobId) {\n      await assertObservationOwnership(this.client, input.sourceId, input.projectId, input.teamId);\n    }\n    if (input.generationJobId) {\n      await assertGenerationJobMatchesSource(this.client, {\n        generationJobId: input.generationJobId,\n        projectId: input.projectId,\n        teamId: input.teamId,\n        sourceType: input.sourceType,\n        sourceId: input.sourceId,\n        agentEventId\n      });\n    }\n","sourceCodeStart":210,"sourceCodeEnd":246,"githubUrl":"https://github.com/thedotmack/claude-mem/blob/d8bc9755e74915e5c3b999181e10a67c889bce2a/src/storage/postgres/observations.ts#L210-L246","documentation":"When sourceType is 'agent_event', the sourceId is required to be the agent event's ID: the resolved agentEventId (explicit agentEventId ?? sourceId) must equal input.sourceId. Passing a different value for sourceId and agentEventId is contradictory, so addSource throws before any database work.","triggerScenarios":"Calling addSource with sourceType='agent_event' and both agentEventId and sourceId supplied where agentEventId !== sourceId; e.g. passing the observation id or a session id as sourceId while supplying the real event id in agentEventId.","commonSituations":"Copy-paste of a manual/session_summary addSource call changed to 'agent_event' without updating sourceId; wrappers that thread distinct ids into both fields; unit tests reusing fixtures from other source types.","solutions":["Set sourceId to the agent event's id whenever sourceType is 'agent_event'.","Omit agentEventId entirely (it defaults from sourceId) instead of passing a second id.","If you intended a non-agent-event source, change sourceType to the matching type ('manual', 'session_summary', etc.)."],"exampleFix":"// before\nawait repo.addSource({ sourceType: 'agent_event', sourceId: sessionId, agentEventId: eventId, ... });\n// after\nawait repo.addSource({ sourceType: 'agent_event', sourceId: eventId, ... });","handlingStrategy":"validation","validationCode":"if (sourceType === 'agent_event' && sourceId !== (agentEventId ?? sourceId)) {\n  throw new Error('agent_event addSource requires sourceId === agentEventId');\n}","typeGuard":"function isConsistentAgentEventSource(input: { sourceType: string; sourceId: string; agentEventId?: string | null }): boolean {\n  return input.sourceType !== 'agent_event' || (input.agentEventId ?? input.sourceId) === input.sourceId;\n}","tryCatchPattern":"try {\n  await repo.addSource(input);\n} catch (e) {\n  if (e instanceof Error && e.message === 'agent_event source_id must equal agent_event_id') {\n    throw new Error(`bad addSource call: sourceId=${input.sourceId} agentEventId=${input.agentEventId}`);\n  }\n  throw e;\n}","preventionTips":["For agent_event sources, only pass sourceId and let agentEventId default from it.","Never reuse addSource input objects across different sourceType values.","Add a unit test asserting agent-event sources always use the event id as sourceId."],"tags":["postgres","invariant","agent-events"],"backgroundTag":"invalid-argument-value","analyzedSha":"d8bc9755e74915e5c3b999181e10a67c889bce2a","analyzedAt":"2026-09-17T16:40:26.182Z","contentChangedAt":"2026-09-17T16:40:26.182Z","schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}