thedotmack/claude-mem · warning
session_not_found
session_not_found
Error message
session_not_found
What it means
404 from the compat summarize route when the endSession pipeline resolves to no session (result.session is null). The adapter looked up the session by contentSessionId within the key's team/project and either found nothing or the end operation could not materialize a session row; the response keeps the legacy shape { status: 'not_found', reason: 'session_not_found' }.
Source
Thrown at src/server/compat/SessionsSummarizeAdapter.ts:122
teamId,
projectId,
contentSessionId: data.contentSessionId,
platformSource,
agentId: null,
agentType: null,
});
const result = await this.options.endSession.end({
sessionId: session.id,
projectId,
teamId,
source: 'http_post_api_sessions_summarize',
apiKeyId: req.authContext?.apiKeyId ?? null,
actorId: null,
sourceAdapter: 'claude-code-compat',
});
if (!result.session) {
res.status(404).json({ status: 'not_found', reason: 'session_not_found' });
return;
}
res.json({
status: 'queued',
sessionId: session.id,
serverSessionId: session.id,
generationJobId: result.outbox?.id ?? null,
transport: result.enqueueState,
});
}
private asyncHandler(fn: (req: Request, res: Response) => Promise<void> | void) {
return (req: Request, res: Response, next: (err?: unknown) => void): void => {
Promise.resolve(fn(req, res)).catch(next);
};
}
}
View on GitHub (pinned to e2d1df569a)
Solutions
- Verify the contentSessionId was actually ingested: check that events for it were accepted (201 from /v1/events) under the same team/project as the key.
- Confirm the API key's project scope matches the project that owns the session.
- Make summarize idempotent on the client: treat 404 session_not_found as terminal, not retryable.
- If the session should exist, query the sessions/events listing for that team to see whether it was ended or never created.
Defensive patterns
Strategy: validation
Validate before calling
// Confirm ingestion before summarizing
const created = await postJson('/v1/events', {
projectId, contentSessionId: sid,
type: 'session.start', // per schema
});
if (created.status !== 201 && created.status !== 200) {
throw new Error(`session ${sid} not ingestible; skipping summarize`);
} Type guard
interface NotFoundBody { status: string; reason: string }
function isSessionNotFound(body: unknown): body is NotFoundBody {
return typeof body === 'object' && body !== null &&
(body as NotFoundBody).status === 'not_found' && (body as NotFoundBody).reason === 'session_not_found';
} Try / catch
const res = await summarize(sid);
if (res.status === 404) {
const body = await res.json();
if (isSessionNotFound(body)) return; // terminal: session absent under this scope
} Prevention
- Summarize only sessions whose start event you saw accepted.
- Keep key's project scope identical between ingestion and summarize calls.
- Treat 404 as non-retryable to avoid loops.
When it happens
Trigger: POST /api/sessions/summarize with a contentSessionId never created in that team/project; summarizing a session whose id belongs to a different project than the key's scope; calling summarize twice where the first call ended and removed/flagged the session so a second call cannot resolve it.
Common situations: Client regenerates session ids per run and summarizes an id from a stale run; key's projectId does not match the project that ingested the session's events; environment mismatch (test key against prod data or vice versa).
Related errors
AI-assisted analysis of thedotmack/claude-mem@e2d1df569a (2026-08-20).
Data as JSON: /api/errors/55137969ce70f22c.
Report an issue: GitHub.