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
- Keep gitHubToken for a static token, or gitHubTokenProvider for dynamic token acquisition — never both
- Remove whichever auth mechanism you are not using from the session config
- 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)