github/copilot-sdk · error · ArgumentException

ConnectionToken must be a non-empty string or null.

Error message

ConnectionToken must be a non-empty string or null.

What it means

For a TcpRuntimeConnection, the constructor requires ConnectionToken to be either null or a non-empty string; an empty string is rejected with ArgumentException. When null, the SDK auto-generates a GUID token so the loopback listener is safe by default.

Solutions

  1. Set ConnectionToken to null to let the SDK auto-generate one
  2. Provide a real non-empty token string
  3. Guard config loading: treat empty-string tokens as null before constructing options

Example fix

// before
tcp.ConnectionToken = Environment.GetEnvironmentVariable("COPILOT_TOKEN") ?? "";
// after
tcp.ConnectionToken = string.IsNullOrEmpty(Environment.GetEnvironmentVariable("COPILOT_TOKEN")) ? null : Environment.GetEnvironmentVariable("COPILOT_TOKEN");
Defensive patterns

Strategy: validation

Validate before calling

tcp.ConnectionToken = string.IsNullOrEmpty(rawToken) ? null : rawToken;

Try / catch

try { client = new CopilotClient(options); } catch (ArgumentException ex) when (ex.Message.Contains("ConnectionToken")) { ((TcpRuntimeConnection)options.Connection).ConnectionToken = null; client = new CopilotClient(options); }

Prevention

When it happens

Trigger: new CopilotClient(options) where options.Connection is a TcpRuntimeConnection whose ConnectionToken is set to string.Empty (Length == 0).

Common situations: Reading the token from an env var or config that is defined but empty (COPILOT_TOKEN=""); initializing string fields to "" as a placeholder; deserializing connection settings where the token came back as an empty string.

Understand the failure class

Background: "Must be a positive integer", "Invalid value", "Unsupported": the invalid-argument-value error family, when a library rejects the value you pass — this error's family across 35 libraries.

Related errors


AI-assisted analysis of github/copilot-sdk@cd8cf15dc3 (2026-09-09). Data as JSON: /api/errors/5a7d878c89df95f0. Report an issue: GitHub.

Appendix: source

Thrown at dotnet/src/Client.cs:163

        {
            throw new ArgumentException(
                $"{nameof(CopilotClientOptions)}.{nameof(CopilotClientOptions.BuiltinPluginDirectories)} " +
                $"must contain only absolute paths: {path}",
                nameof(options));
        }

        switch (_connection)
        {
            case StdioRuntimeConnection:
                break;

            case InProcessRuntimeConnection:
                break;

            case TcpRuntimeConnection tcp:
                if (tcp.ConnectionToken is { Length: 0 })
                {
                    throw new ArgumentException("ConnectionToken must be a non-empty string or null.", nameof(options));
                }
                // Auto-generate a connection token when the SDK spawns the runtime over TCP
                // so the loopback listener is safe by default.
                tcp.ConnectionToken ??= Guid.NewGuid().ToString();
                break;

            case UriRuntimeConnection uri:
                if (string.IsNullOrEmpty(uri.Url))
                {
                    throw new ArgumentException("UriRuntimeConnection.Url must be a non-empty string.", nameof(options));
                }
                if (!string.IsNullOrEmpty(_options.GitHubToken) || _options.UseLoggedInUser != null)
                {
                    throw new ArgumentException("GitHubToken and UseLoggedInUser cannot be combined with RuntimeConnection.ForUri (the existing runtime manages its own auth).", nameof(options));
                }
                var parsed = ParseRuntimeUrl(uri.Url);
                _optionsHost = parsed.Host.Trim('[', ']');
                _optionsPort = parsed.Port;

View on GitHub (pinned to cd8cf15dc3)