github/copilot-sdk · error · IllegalArgumentException
GitHubToken and UseLoggedInUser cannot be used with CliUrl…
Error message
GitHubToken and UseLoggedInUser cannot be used with CliUrl (external server manages its own auth)
What it means
When CopilotClient connects to an external server via CliUrl, that server manages its own authentication, so supplying GitHubToken or UseLoggedInUser is contradictory. The constructor throws IllegalArgumentException to prevent conflicting auth configuration. Auth options are only meaningful when the client drives a local CLI.
Solutions
- Omit githubToken and useLoggedInUser when cliUrl is set — the external server authenticates itself.
- Conditionally set auth options only when cliPath/local-CLI mode is used.
- Move auth configuration to the external server instead of the client options.
Example fix
// before
options.setCliUrl("http://localhost:8080");
options.setGitHubToken(token); // not allowed with CliUrl
// after
options.setCliUrl("http://localhost:8080");
// no auth options — external server manages auth Defensive patterns
Strategy: validation
Validate before calling
boolean external = options.getCliUrl() != null && !options.getCliUrl().isEmpty();
if (external && (options.getGitHubToken() != null || options.getUseLoggedInUser().isPresent())) {
options.setGitHubToken(null);
} Try / catch
try {
client = new CopilotClient(options);
} catch (IllegalArgumentException e) {
if (e.getMessage().contains("cannot be used with CliUrl")) {
options.setGitHubToken(null);
client = new CopilotClient(options);
} else throw e;
} Prevention
- Only set auth options in local-CLI mode; the external server owns its auth.
- Don't wire environment tokens (e.g. GITHUB_TOKEN) into options unconditionally.
- Use separate option builders for external-server and local-CLI modes.
When it happens
Trigger: Constructing CopilotClient with a non-empty cliUrl plus either a non-null githubToken or a present useLoggedInUser option.
Common situations: Reusing a shared options builder that always sets GitHubToken; switching from local CLI to external-server mode without removing auth fields; environment-injected tokens (e.g. GITHUB_TOKEN) wired into options unconditionally.
Understand the failure class
Background: Conflicting config options: "cannot be used together" — configuration validation errors across open-source libraries — this error's family across 162 libraries.
Related errors
- CliUrl is mutually exclusive with CliPath
- TcpConnectionToken must be a non-empty string
- TcpConnectionToken cannot be used with UseStdio = true
- CopilotClient was created with Mode = EMPTY but neither…
- Invalid value ' '. Expected 'inprocess', 'stdio', or unset.
AI-assisted analysis of github/copilot-sdk@cd8cf15dc3 (2026-09-09).
Data as JSON: /api/errors/7ba7fdad278d869b.
Report an issue: GitHub.
Appendix: source
Thrown at java/sdk/src/main/java/com/github/copilot/CopilotClient.java:187
}
}
this.runtimeConnection = requestedConnection;
// When cliUrl is set, auto-correct useStdio since we're connecting via TCP
if (this.options.getCliUrl() != null && !this.options.getCliUrl().isEmpty()) {
this.options.setUseStdio(false);
}
// Validate mutually exclusive options: cliUrl and cliPath cannot both be set
if (this.options.getCliUrl() != null && !this.options.getCliUrl().isEmpty()
&& this.options.getCliPath() != null) {
throw new IllegalArgumentException("CliUrl is mutually exclusive with CliPath");
}
// Validate auth options with external server
if (this.options.getCliUrl() != null && !this.options.getCliUrl().isEmpty()
&& (this.options.getGitHubToken() != null || this.options.getUseLoggedInUser().isPresent())) {
throw new IllegalArgumentException(
"GitHubToken and UseLoggedInUser cannot be used with CliUrl (external server manages its own auth)");
}
// Validate tcpConnectionToken
if (this.options.getTcpConnectionToken() != null) {
if (this.options.getTcpConnectionToken().isEmpty()) {
throw new IllegalArgumentException("TcpConnectionToken must be a non-empty string");
}
if (this.options.isUseStdio()) {
throw new IllegalArgumentException("TcpConnectionToken cannot be used with UseStdio = true");
}
}
// Compute effective connection token: use provided, or auto-generate for
// SDK-spawned TCP mode, or null for stdio/external server
boolean sdkSpawnsCli = !this.options.isUseStdio()
&& (this.options.getCliUrl() == null || this.options.getCliUrl().isEmpty());
this.effectiveConnectionToken = this.options.getTcpConnectionToken() != nullView on GitHub (pinned to cd8cf15dc3)