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

  1. Recreate or re-register the session before issuing calls that reference its sessionId.
  2. After a client restart, re-establish sessions with the runtime instead of reusing stale session ids.
  3. Verify you are talking to the same client instance that created the session (check for multiple client instances).
  4. 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

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


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)