github/copilot-sdk · error · InvalidOperationException
Failed to delete session
Error message
Failed to delete session {sessionId}: {response.Error} What it means
Thrown when the session.delete RPC completes but the CLI responds with Success=false, with response.Error carrying the server-side reason. The library surfaces that server message verbatim so the developer knows why deletion failed. The local session cache is only cleaned up when deletion succeeds.
Solutions
- Read response.Error embedded in the message for the server-side cause and fix accordingly (e.g. unknown session = already deleted)
- Guard against double deletion: track whether the session was already deleted before calling DeleteSessionAsync again
- Verify the sessionId matches one created on the same connection/client instance
- If the session is already gone, treat this as idempotent: catch InvalidOperationException and continue cleanup
Example fix
// before
await client.DeleteSessionAsync(sessionId);
// after
try { await client.DeleteSessionAsync(sessionId); }
catch (InvalidOperationException) { /* already deleted on server; ignore */ } Defensive patterns
Strategy: try-catch
Validate before calling
if (_deletedSessions.Contains(sessionId)) return; // skip duplicate delete
Try / catch
try { await client.DeleteSessionAsync(sessionId); }
catch (InvalidOperationException ex) when (ex.Message.StartsWith("Failed to delete session"))
{ logger.LogWarning(ex, "session delete rejected (possibly already gone)"); } Prevention
- Track deleted session IDs to avoid double deletes
- Only delete sessions created on the same client/connection
- Treat delete as best-effort during teardown
- Surface response.Error text in your logs
When it happens
Trigger: Calling DeleteSessionAsync (or disposing a session that deletes on close) for a sessionId the server rejects: already deleted, unknown to the server, or the server reports an internal error deleting it.
Common situations: Double-dispose / deleting the same session twice; deleting a session created on a different connection; CLI crash or restart that invalidated the session; server-side permission or lifecycle errors.
Related errors
- session.create response did not include a sessionId.
- session.create returned sessionId
- {response.Error ?? "Failed to set foreground session"}
- Unknown session
- No session found for sessionId
AI-assisted analysis of github/copilot-sdk@cd8cf15dc3 (2026-09-09).
Data as JSON: /api/errors/020c479f0eb1ba5a.
Report an issue: GitHub.
Appendix: source
Thrown at dotnet/src/Client.cs:1753
/// irreversible. The session cannot be resumed after deletion.
/// </remarks>
/// <example>
/// <code>
/// await client.DeleteSessionAsync("session-123");
/// </code>
/// </example>
public async Task DeleteSessionAsync(string sessionId, CancellationToken cancellationToken = default)
{
ArgumentNullException.ThrowIfNull(sessionId);
var connection = await EnsureConnectedAsync(cancellationToken);
var response = await InvokeRpcAsync<DeleteSessionResponse>(
connection.Rpc, "session.delete", [new DeleteSessionRequest(sessionId)], cancellationToken);
if (!response.Success)
{
throw new InvalidOperationException($"Failed to delete session {sessionId}: {response.Error}");
}
if (_sessions.TryRemove(sessionId, out var session))
{
session.ReleaseGitHubTokenProviderRegistration();
}
}
/// <summary>
/// Lists all sessions known to the Copilot server.
/// </summary>
/// <param name="filter">Optional filter to narrow down the session list by cwd, git root, repository, or branch.</param>
/// <param name="cancellationToken">A <see cref="CancellationToken"/> that can be used to cancel the operation.</param>
/// <returns>A task that resolves with a list of <see cref="SessionMetadata"/> for all available sessions.</returns>
/// <exception cref="InvalidOperationException">Thrown when the client is not connected.</exception>
/// <example>
/// <code>
/// var sessions = await client.ListSessionsAsync();View on GitHub (pinned to cd8cf15dc3)