github/copilot-sdk · error · RuntimeException

session.create returned sessionId

Error message

session.create returned sessionId ${returnedId} but the caller requested ${localSessionId}

What it means

When createSession is called with an explicit sessionId, CopilotClient validates that the server echoed the same id back. If the server returned a different sessionId than the caller requested, the client throws to prevent operating on a session the caller cannot address.

Solutions

  1. Stop pre-assigning a sessionId and let createSession use the server-generated id
  2. Ensure the component that minted localSessionId is the same one that owns session.create handling
  3. Check for duplicate clients or reconnect logic reusing an old session id after server restart
  4. Enable FINE timing logs to compare requested vs returned ids

Example fix

// before
client.createSession(new CreateSessionOptions().setSessionId(myFixedId));
// after
CopilotSession session = client.createSession(new CreateSessionOptions());
String id = session.getSessionId();
Defensive patterns

Strategy: validation

Validate before calling

if (requestedSessionId != null && !requestedSessionId.isBlank()) {
    // be ready for the server to reject or reassign client-supplied ids
}

Try / catch

try {
    client.createSession(optsWithFixedId);
} catch (RuntimeException e) {
    if (e.getMessage().startsWith("session.create returned sessionId")) {
        // fall back to server-assigned id
    }
}

Prevention

When it happens

Trigger: Calling createSession(options) with a preset sessionId (localSessionId != null) while the server's session.create handler generates or returns its own distinct sessionId.

Common situations: Multiple clients racing to create sessions with the same id; a server that ignores client-supplied session ids; stale id reuse after a server restart; tests seeding ids that the server does not honor.

Understand the failure class

Background: "invalid response format", "malformed payload", "missing data field": when an API returns 200 but the response shape is wrong — this error's family across 23 libraries.

Related errors


AI-assisted analysis of github/copilot-sdk@cd8cf15dc3 (2026-09-09). Data as JSON: /api/errors/e369ce755845f596. Report an issue: GitHub.

Appendix: source

Thrown at java/sdk/src/main/java/com/github/copilot/CopilotClient.java:1018

                request.setGitHubTokenProviderRegistrationId(tokenRegistration.id());
                if (preRegisteredSessionHolder[0] != null) {
                    preRegisteredSessionHolder[0].setGitHubTokenProviderRegistration(tokenRegistration);
                }
            }

            long rpcNanos = System.nanoTime();
            return connection.rpc.invoke("session.create", request, CreateSessionResponse.class)
                    .thenCompose(response -> {
                        String returnedId = response.sessionId();
                        LoggingHelpers.logTiming(LOG, Level.FINE,
                                "CopilotClient.createSession session creation request completed. Elapsed={Elapsed}, SessionId="
                                        + (returnedId != null ? returnedId : localSessionId),
                                rpcNanos);
                        if (returnedId == null || returnedId.isEmpty()) {
                            throw new RuntimeException("session.create response did not include a sessionId");
                        }
                        if (localSessionId != null && !localSessionId.equals(returnedId)) {
                            throw new RuntimeException("session.create returned sessionId " + returnedId
                                    + " but the caller requested " + localSessionId);
                        }
                        CopilotSession session = preRegisteredSessionHolder[0] != null
                                ? preRegisteredSessionHolder[0]
                                : initializeSession.apply(returnedId);
                        preRegisteredSessionHolder[0] = session;
                        if (tokenRegistration != null) {
                            session.setGitHubTokenProviderRegistration(tokenRegistration);
                        }
                        registeredIdHolder[0] = returnedId;
                        CompletableFuture<?> interest = config.getOnMcpAuthRequest() != null
                                ? session.getRpc().eventLog.registerInterest(
                                        new SessionEventLogRegisterInterestParams(returnedId, "mcp.oauth_required"))
                                : CompletableFuture.completedFuture(null);
                        session.setWorkspacePath(response.workspacePath());
                        session.setCapabilities(response.capabilities());
                        session.setOpenCanvases(response.openCanvases());

View on GitHub (pinned to cd8cf15dc3)