github/copilot-sdk · error

gitHubToken and gitHubTokenProvider are mutually exclusive

Error message

gitHubToken and gitHubTokenProvider are mutually exclusive

What it means

Session-creation option validation: the SessionConfig supplied both gitHubToken (an inline token value) and gitHubTokenProvider (a provider callback/object). These are alternative ways to supply GitHub auth, and the client rejects configs that set both because precedence would be ambiguous.

Solutions

  1. Keep gitHubToken for a static token, or gitHubTokenProvider for dynamic token acquisition — never both
  2. Remove whichever auth mechanism you are not using from the session config
  3. If migrating from static to provider-based tokens, delete the old gitHubToken field rather than leaving it set
Defensive patterns

Strategy: validation

When it happens

Trigger: Thrown at nodejs/src/client.ts:1511 when the library encounters an invalid state.

Common situations: See trigger scenarios.


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

Appendix: source

Thrown at nodejs/src/client.ts:1511

        try {
            await session.rpc.options.update(patch);
        } catch (e) {
            // The runtime session exists but the post-create options
            // patch failed — best-effort disconnect so we don't leak
            // it (in empty mode it would otherwise keep running with
            // permissive defaults).
            try {
                await session.disconnect();
            } catch {
                // Swallow: original error is the one the caller needs.
            }
            throw e;
        }
    }

    async createSession(config: SessionConfig): Promise<CopilotSession> {
        if (config.gitHubToken !== undefined && config.gitHubTokenProvider !== undefined) {
            throw new Error("gitHubToken and gitHubTokenProvider are mutually exclusive");
        }
        if (!this.connection) {
            await this.start();
        }

        const modeDefaults = this.configDefaultsForMode();
        config = { ...modeDefaults, ...config };
        config.customAgentsLocalOnly ??= modeDefaults.customAgentsLocalOnly;
        config.systemMessage = this.getSystemMessageConfigForMode(config.systemMessage);

        // For cloud sessions, let the CLI/server assign the session id and
        // register the session lazily once the response arrives. For non-cloud
        // sessions we generate the id client-side (when the caller didn't
        // supply one) so the session can be registered BEFORE the RPC — the
        // CLI may issue session-scoped requests (e.g. `sessionFs.writeFile`
        // for workspace metadata) during `session.create` processing, before
        // it has sent the response.
        const callerSessionId = config.sessionId;

View on GitHub (pinned to cd8cf15dc3)