github/copilot-sdk · error · ArgumentException

CopilotClient is in Mode = CopilotClientMode.Empty but the…

Error message

CopilotClient is in Mode = CopilotClientMode.Empty but the session config did not specify AvailableTools. Empty mode requires every session to explicitly opt into the tools it wants — e.g. `AvailableTools = new ToolSet().AddBuiltIn(BuiltInTools.Isolated)`.

What it means

The CopilotClient constructor throws this ArgumentException when the client is in CopilotClientMode.Empty and a session config does not specify AvailableTools. Empty mode intentionally exposes zero tools by default; every session must explicitly opt in to the tools it wants, so a config without AvailableTools is rejected.

Solutions

  1. Set AvailableTools on the session config, e.g. AvailableTools = new ToolSet().AddBuiltIn(BuiltInTools.Isolated).
  2. Use a different CopilotClientMode if you don't need the strict empty-mode behavior.
  3. Update all shared/default session config factories used with the Empty-mode client.

Example fix

// before
var config = new SessionConfig(); // no AvailableTools
var session = await client.CreateSessionAsync(config); // throws in Empty mode
// after
var config = new SessionConfig { AvailableTools = new ToolSet().AddBuiltIn(BuiltInTools.Isolated) };
var session = await client.CreateSessionAsync(config);
Defensive patterns

Strategy: validation

Validate before calling

if (mode == CopilotClientMode.Empty && sessionConfig.AvailableTools is null)
    throw new ArgumentException("Empty mode requires AvailableTools on every session config.");

Type guard

static bool IsValidForEmptyMode(CopilotClientMode mode, SessionConfigBase cfg) => mode != CopilotClientMode.Empty || cfg.AvailableTools is not null;

Try / catch

try { session = await client.CreateSessionAsync(config); }
catch (ArgumentException ex) when (ex.Message.Contains("CopilotClientMode.Empty")) { config.AvailableTools ??= new ToolSet().AddBuiltIn(BuiltInTools.Isolated); session = await client.CreateSessionAsync(config); }

Prevention

When it happens

Trigger: new CopilotClient(options with Mode = CopilotClientMode.Empty, ...) then calling CreateSessionAsync with a config whose AvailableTools is null. ValidateToolFilterList/Empty-mode check runs per session config.

Common situations: Switching the client to Empty mode for least-privilege but forgetting to update existing session configs; shared/default session configs written before the mode change; tests that create bare SessionConfig objects.

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/aa511867e5930c00. Report an issue: GitHub.

Appendix: source

Thrown at dotnet/src/Client.cs:973

            }
        }
    }

    /// <summary>
    /// Resolves <see cref="SessionConfigBase.AvailableTools"/> /
    /// <see cref="SessionConfigBase.ExcludedTools"/> for the wire payload,
    /// validating empty-mode requirements. <c>toolFilterPrecedence</c> is
    /// always <c>excluded</c> so SDK consumers get composable allowlist /
    /// denylist semantics.
    /// </summary>
    private (IList<string>? AvailableTools, IList<string>? ExcludedTools, OptionsUpdateToolFilterPrecedence ToolFilterPrecedence) ResolveToolFilterOptions(SessionConfigBase config)
    {
        ValidateToolFilterList(nameof(SessionConfigBase.AvailableTools), config.AvailableTools);
        ValidateToolFilterList(nameof(SessionConfigBase.ExcludedTools), config.ExcludedTools);

        if (_options.Mode == CopilotClientMode.Empty && config.AvailableTools is null)
        {
            throw new ArgumentException(
                "CopilotClient is in Mode = CopilotClientMode.Empty but the session config did " +
                "not specify AvailableTools. Empty mode requires every session to explicitly " +
                "opt into the tools it wants — e.g. " +
                "`AvailableTools = new ToolSet().AddBuiltIn(BuiltInTools.Isolated)`.",
                nameof(config));
        }

        return (config.AvailableTools, config.ExcludedTools, OptionsUpdateToolFilterPrecedence.Excluded);
    }

    /// <summary>
    /// Applies mode-specific defaults to a session config in place. Caller
    /// values win — only fields left unset by the caller are filled in.
    /// </summary>
    private void ApplyConfigDefaultsForMode(SessionConfigBase config)
    {
        if (_options.Mode == CopilotClientMode.Empty)
        {

View on GitHub (pinned to cd8cf15dc3)