github/copilot-sdk · error · ArgumentException

Unknown session

Error message

Unknown session {sessionId}

What it means

The RPC layer resolves incoming client-session-API calls to a CopilotSession via GetSession(sessionId); if no session with that id is tracked, an ArgumentException with "Unknown session {sessionId}" is thrown. This is registered globally for all client-session API handlers, so any RPC arriving for a stale or foreign session id surfaces here.

Solutions

  1. Verify the session was created by this client instance and keep a reference to its SessionId.
  2. Don't dispose sessions (or the whole client) while the CLI may still reference them; await session teardown before disposing.
  3. If reconnecting, recreate sessions rather than reusing ids from a previous client lifetime.
  4. Wrap session lookups with a null check instead of assuming the id is valid.

Example fix

// before
var session = client.GetSession(sessionId);
await session.SendAsync(msg); // ArgumentException: Unknown session

// after
var session = client.GetSession(sessionId);
if (session is null)
{
    session = await client.CreateSessionAsync(); // recreate instead of using stale id
}
await session.SendAsync(msg);
Defensive patterns

Strategy: try-catch

Validate before calling

if (client.GetSession(sessionId) is null)
{
    // recreate or skip
}

Type guard

bool IsKnownSession(CopilotClient c, string id) => c.GetSession(id) is not null;

Try / catch

try { var s = GetOrThrow(sessionId); ... }
catch (ArgumentException ex) when (ex.Message.StartsWith("Unknown session"))
{ /* recreate session or drop stale request */ }

Prevention

When it happens

Trigger: An RPC method call targeting ClientSessionApis arrives with a sessionId that is not in the client's _sessions map (GetSession returned null), e.g. after the session was disposed or the id never existed.

Common situations: CLI sends a notification/request for a session the client already disposed; a resumed/reconnected client receives events for sessions created by a previous client instance; a typo'd or stale sessionId cached by caller code.

Understand the failure class

Background: Record Not Found Errors: "not found", RecordNotFound, and "was not found" — what they mean and how to fix them — this error's family across 28 libraries.

Related errors


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

Appendix: source

Thrown at dotnet/src/Client.cs:2692

            }

            rpc = new JsonRpc(
                outputStream,
                inputStream,
                SerializerOptionsForMessageFormatter,
                _logger);

            var handler = new RpcHandler(this);
            rpc.SetLocalRpcMethod("session.event", handler.OnSessionEvent);
            rpc.SetLocalRpcMethod("session.lifecycle", handler.OnSessionLifecycle);
            rpc.SetLocalRpcMethod("userInput.request", handler.OnUserInputRequest);
            rpc.SetLocalRpcMethod("exitPlanMode.request", handler.OnExitPlanModeRequest);
            rpc.SetLocalRpcMethod("autoModeSwitch.request", handler.OnAutoModeSwitchRequest);
            rpc.SetLocalRpcMethod("hooks.invoke", handler.OnHooksInvoke);
            rpc.SetLocalRpcMethod("systemMessage.transform", handler.OnSystemMessageTransform);
            ClientSessionApiRegistration.RegisterClientSessionApiHandlers(rpc, sessionId =>
            {
                var session = GetSession(sessionId) ?? throw new ArgumentException($"Unknown session {sessionId}");
                return session.ClientSessionApis;
            });
            if (_clientGlobalApis is not null)
            {
                ClientGlobalApiRegistration.RegisterClientGlobalApiHandlers(rpc, _clientGlobalApis);
            }
            rpc.StartListening();
            _ = CancelExternalToolsWhenConnectionClosesAsync(rpc);
            LoggingHelpers.LogTiming(_logger, LogLevel.Debug, null,
                "CopilotClient.ConnectToServerAsync transport setup complete. Elapsed={Elapsed}",
                setupTimestamp);

            var connection = new Connection(rpc, cliProcess, networkStream, stderrPump, ffiHost);
            _serverRpc = connection.Server;

            return connection;
        }
        catch

View on GitHub (pinned to cd8cf15dc3)