github/copilot-sdk · error
No session found for sessionId
Error message
No session found for sessionId: ${sessionId} What it means
When the runtime calls back into the client for a session-scoped API, the client looks up the sessionId in its sessions map and throws if the id is unknown. This means the runtime referenced a session this client instance never registered, or the session was already removed. It is a server-to-client callback dispatch failure.
Solutions
- Recreate or re-register the session before issuing calls that reference its sessionId.
- After a client restart, re-establish sessions with the runtime instead of reusing stale session ids.
- Verify you are talking to the same client instance that created the session (check for multiple client instances).
- Handle session-expired callbacks by deleting downstream references when a session ends so no stale ids are sent.
Example fix
// before
const session = await createSession(client);
await client.stop();
// ... later, with stale sessionId from `session`
await resumeSession(client, session.id); // throws: session map lost
// after
await client.stop();
client = new CopilotClient({ ... });
await client.start();
const session = await createSession(client); // fresh session id
await resumeSession(client, session.id); Defensive patterns
Strategy: try-catch
Validate before calling
if (!client.hasSession?.(sessionId)) {
const session = await createSession(client); // re-register before use
sessionId = session.id;
} Try / catch
try {
await useSession(client, sessionId);
} catch (err) {
if (err instanceof Error && err.message.startsWith('No session found')) {
const fresh = await createSession(client);
sessionId = fresh.id;
await useSession(client, sessionId);
} else {
throw err;
}
} Prevention
- Recreate sessions after any client restart; never reuse persisted session ids.
- Drop cached session ids as soon as a session is deleted or expires.
- Ensure only one client instance owns a given session.
- Wrap session-scoped calls in a create-if-missing retry helper.
When it happens
Trigger: A runtime callback arrives with a sessionId that was never created via this client (e.g. resume/attach to a session owned by another process), or the session was deleted/expired and later callbacks still reference its id.
Common situations: Client restarted and lost in-memory session state while the runtime still holds old session ids; calling session APIs after the session was deleted; sessionId typos or ids from a previous connection being replayed; multiple client instances where the callback lands on the wrong one.
Understand the failure class
Background: 'Could not be found', 'does not exist', 'not found in database': the resource-not-found family when an ID, slug, key, or URI lookup comes back empty — this error's family across 20 libraries.
Related errors
- Session not found
- session.create returned sessionId
- session.create response did not include a sessionId
- session.create returned sessionId
- Failed to delete session
AI-assisted analysis of github/copilot-sdk@cd8cf15dc3 (2026-09-09).
Data as JSON: /api/errors/9aacb5c752715c8c.
Report an issue: GitHub.
Appendix: source
Thrown at nodejs/src/client.ts:3044
params: AutoModeSwitchRequest & { sessionId: string }
): Promise<{ response: AutoModeSwitchResponse }> =>
await this.handleAutoModeSwitchRequest(params)
);
this.connection.onRequest(
"systemMessage.transform",
async (params: {
sessionId: string;
sections: Record<string, { content: string }>;
}): Promise<{ sections: Record<string, { content: string }> }> =>
await this.handleSystemMessageTransform(params)
);
// Register client session API handlers.
const sessions = this.sessions;
registerClientSessionApiHandlers(this.connection, (sessionId) => {
const session = sessions.get(sessionId);
if (!session) throw new Error(`No session found for sessionId: ${sessionId}`);
return session.clientSessionApis;
});
// Register client *global* API handlers (e.g. LLM inference) on the
// same connection. These methods carry no implicit sessionId dispatch
// — the runtime calls into a single handler for the whole connection.
registerClientGlobalApiHandlers(this.connection, this.clientGlobalHandlers);
// `hooks.invoke` is an internal RPC method: the runtime calls it to
// invoke a hook callback on the client. Route each call to the matching
// session's dispatcher. Not part of the public ClientGlobalApiHandlers
// interface because HookInvokeRequest/HookType are internal types.
this.connection.onRequest(
"hooks.invoke",
async (params: { sessionId: string; hookType: string; input: unknown }) => {
return await this.handleHooksInvoke(params);
}
);View on GitHub (pinned to cd8cf15dc3)