toeverything/AFFiNE · error · CopilotSessionNotFound
copilot_session_not_found
copilot_session_not_found
Error message
Copilot session not found.
What it means
CopilotSessionNotFound thrown at the top of CopilotSessionModel.update() (copilot-session.ts:645-659). getExists(sessionId, select, { userId }) queries aiSession with the caller's userId and deletedAt: null, returning null when the id does not exist, belongs to a different user, or was soft-deleted; update() converts that null into this error before touching any field. The internalCall flag only relaxes later guards (action/fork rules), not this existence check.
Solutions
- Re-resolve the session for the current user (e.g. via has(sessionId, userId)) and use a live id
- If the session was deleted, create a new session instead of updating
- Verify the authenticated userId matches the session owner
Example fix
// before
await sessions.update({ userId, sessionId: staleId, title });
// after
let sessionId = staleId;
if (!(await sessions.has(sessionId, userId))) {
sessionId = await sessions.create({ userId, workspaceId, docId });
}
await sessions.update({ userId, sessionId, title }); Defensive patterns
Strategy: validation
Validate before calling
let sessionId = requestedId;
if (!(await sessions.has(sessionId, userId))) {
sessionId = await sessions.create({ userId, workspaceId, docId });
}
await sessions.update({ userId, sessionId, ...patch }); Try / catch
try {
await sessions.update(options);
} catch (e) {
if (e instanceof CopilotSessionNotFound) {
// re-resolve or create a session; surface 'conversation expired' to the client
}
throw e;
} Prevention
- Always scope session lookups by the authenticated userId
- Refresh stale session ids from the server before mutations
- Handle not-found as a UX state (start a new chat), not an error page
When it happens
Trigger: update({ userId, sessionId, ... }) with an unknown, foreign, or soft-deleted sessionId - wrong/expired id, session owned by another user, or a session removed by cleanup.
Common situations: Stale sessionId persisted in localStorage after the session was cleaned up; another tab or device deleted the chat; sending an id from a different user's account during testing.
Related errors
- copilot_session_not_found
- Session not found
- blob_not_found
- copilot_message_not_found
- copilot_prompt_invalid
AI-assisted analysis of toeverything/AFFiNE@b4c8548c09 (2026-08-18).
Data as JSON: /api/errors/864b2bb50710b34a.
Report an issue: GitHub.
Appendix: source
Thrown at packages/backend/server/src/models/copilot-session.ts:658
options: UpdateChatSessionOptions,
internalCall = false
): Promise<string> {
const { userId, sessionId, docId, promptName, pinned, title } = options;
const sanitizedTitle = this.sanitizeString(title);
const session = await this.getExists(
sessionId,
{
id: true,
workspaceId: true,
docId: true,
parentSessionId: true,
pinned: true,
promptAction: true,
},
{ userId }
);
if (!session) {
throw new CopilotSessionNotFound();
}
// not allow to update action session
if (!internalCall) {
if (session.promptAction) {
throw new CopilotSessionInvalidInput(
`Cannot update action: ${session.id}`
);
} else if (docId && session.parentSessionId) {
throw new CopilotSessionInvalidInput(
`Cannot update docId for forked session: ${session.id}`
);
}
}
let nextPromptAction: string | null | undefined;
if (promptName) {
nextPromptAction = options.promptAction;View on GitHub (pinned to b4c8548c09)