github/copilot-sdk · error · IllegalArgumentException
CopilotClient is in Mode = EMPTY but the session config did…
Error message
CopilotClient is in Mode = EMPTY but the session config did not specify availableTools. Empty mode requires every session to explicitly opt into the tools it wants — e.g. setAvailableTools(new ToolSet().addBuiltIn(BuiltInTools.ISOLATED)).
What it means
In CopilotClientMode.EMPTY, no default tool set is assumed; every session must explicitly opt into the tools it wants via the session config's availableTools. If a createSession-style call omits availableTools, the constructor throws IllegalArgumentException and removes the partially registered session, leaving no orphan state.
Solutions
- Call setAvailableTools(...) on the session config, e.g. new ToolSet().addBuiltIn(BuiltInTools.ISOLATED)
- Or switch the client to a non-EMPTY mode if implicit tool defaults are desired
- Audit all session-creation call sites to ensure each passes availableTools
Example fix
// before SessionConfig config = new SessionConfig(); // after SessionConfig config = new SessionConfig(); config.setAvailableTools(new ToolSet().addBuiltIn(BuiltInTools.ISOLATED));
Defensive patterns
Strategy: validation
Validate before calling
if (client.getOptions().getMode() == CopilotClientMode.EMPTY && sessionConfig.getAvailableTools() == null) throw new IllegalStateException("EMPTY mode requires setAvailableTools on every session config"); Try / catch
try { client.createSession(config).join(); } catch (IllegalArgumentException e) { if (e.getMessage().contains("Mode = EMPTY but the session config did not specify")) { config.setAvailableTools(new ToolSet().addBuiltIn(BuiltInTools.ISOLATED)); } else throw e; } Prevention
- Use a session-config factory that always sets availableTools in EMPTY mode
- Audit every createSession call site when adopting EMPTY mode
- Default to an explicit minimal ToolSet rather than null
When it happens
Trigger: Creating a session on a client in Mode = EMPTY where config.getAvailableTools() == null (setAvailableTools never called on the session config).
Common situations: Migrating a client to EMPTY mode for least-privilege tooling but not updating every session creation site; dynamic session configs where the tool set was conditionally skipped.
Understand the failure class
Background: "is required", "must be set", "missing required field": configuration validation errors across open-source libraries — this error's family across 36 libraries.
Related errors
- CopilotClient was created with Mode = EMPTY but neither…
- CopilotClient is in Mode = EMPTY but the resume session…
- CopilotClient is in Mode = CopilotClientMode.Empty but the…
- No session found for sessionId
- Session not found
AI-assisted analysis of github/copilot-sdk@cd8cf15dc3 (2026-09-09).
Data as JSON: /api/errors/6c6def31526c79f3.
Report an issue: GitHub.
Appendix: source
Thrown at java/sdk/src/main/java/com/github/copilot/CopilotClient.java:961
var request = SessionRequestBuilder.buildCreateRequest(config, localSessionId, options.getMode());
if (extracted.wireSystemMessage() != config.getSystemMessage()) {
request.setSystemMessage(extracted.wireSystemMessage());
}
// Opt this session into GitHub telemetry forwarding when a
// connection-level handler is registered (mirrors the runtime's
// hand-written capability flag, not part of the codegen'd contract).
if (options.getOnGitHubTelemetry() != null) {
request.setEnableGitHubTelemetryForwarding(true);
}
// Empty mode: validate availableTools and set toolFilterPrecedence
if (options.getMode() == CopilotClientMode.EMPTY) {
if (config.getAvailableTools() == null) {
if (registeredIdHolder[0] != null) {
sessions.remove(registeredIdHolder[0]);
}
throw new IllegalArgumentException(
"CopilotClient is in Mode = EMPTY but the session config did not specify "
+ "availableTools. Empty mode requires every session to explicitly opt into "
+ "the tools it wants — e.g. setAvailableTools(new ToolSet().addBuiltIn(BuiltInTools.ISOLATED)).");
}
request.setToolFilterPrecedence("excluded");
if (request.getSkipEmbeddingRetrieval() == null) {
request.setSkipEmbeddingRetrieval(true);
}
if (request.getEmbeddingCacheStorage() == null) {
request.setEmbeddingCacheStorage("in-memory");
}
if (request.getEnableOnDemandInstructionDiscovery() == null) {
request.setEnableOnDemandInstructionDiscovery(false);
}
if (request.getEnableFileHooks() == null) {
request.setEnableFileHooks(false);
}
if (request.getEnableHostGitOperations() == null) {View on GitHub (pinned to cd8cf15dc3)