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

  1. Call setAvailableTools(...) on the session config, e.g. new ToolSet().addBuiltIn(BuiltInTools.ISOLATED)
  2. Or switch the client to a non-EMPTY mode if implicit tool defaults are desired
  3. 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

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


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)