github/copilot-sdk · error · RuntimeException

Failed to delete session

Error message

Failed to delete session ${sessionId}: ${response.error()}

What it means

deleteSession invokes the session.delete RPC; the server replies with success=false plus an error detail when it cannot delete the session. The client surfaces that as a RuntimeException inside the returned CompletableFuture, so it arrives as a failed future (or unwrapped at join).

Solutions

  1. Log response.error() from the failed future to learn the server's reason
  2. Treat unknown-session errors as idempotent success in cleanup code
  3. Check session state (is it still running?) before deleting; stop it first
  4. Regenerate the session if the id no longer exists on the server

Example fix

// before
client.deleteSession(id).join(); // throws
// after
client.deleteSession(id)
    .exceptionally(ex -> { log.warn("delete failed (ignoring): {}", ex.getMessage()); return null; })
    .join();
Defensive patterns

Strategy: try-catch

Validate before calling

if (!client.sessions.containsKey(sessionId) /* or equivalent liveness check */) {
    // treat as already-deleted; skip RPC
}

Try / catch

client.deleteSession(id)
    .exceptionally(ex -> {
        log.warn("Failed to delete session {}: {}", id, ex.getMessage());
        return null; // idempotent cleanup
    });

Prevention

When it happens

Trigger: Calling deleteSession(sessionId) where the server rejects deletion — unknown/expired sessionId, session still active, or server-side lock — and response.success() is false.

Common situations: Deleting a session that already terminated server-side; double-delete after a timeout; id mismatch after reconnect; server crash recovery leaving orphan ids.

Related errors


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

Appendix: source

Thrown at java/sdk/src/main/java/com/github/copilot/CopilotClient.java:1589

     * Permanently deletes a session and all its data from disk, including
     * conversation history, planning state, and artifacts.
     * <p>
     * Unlike {@link CopilotSession#close()}, which only releases in-memory
     * resources and preserves session data for later resumption, this method is
     * irreversible. The session cannot be resumed after deletion.
     *
     * @param sessionId
     *            the ID of the session to delete
     * @return a future that completes when the session is deleted
     * @throws RuntimeException
     *             if the deletion fails
     */
    public CompletableFuture<Void> deleteSession(String sessionId) {
        return ensureConnected().thenCompose(connection -> connection.rpc
                .invoke("session.delete", Map.of("sessionId", sessionId), DeleteSessionResponse.class)
                .thenAccept(response -> {
                    if (!response.success()) {
                        throw new RuntimeException("Failed to delete session " + sessionId + ": " + response.error());
                    }
                    CopilotSession session = sessions.remove(sessionId);
                    if (session != null) {
                        session.releaseGitHubTokenProviderRegistration();
                    }
                }));
    }

    /**
     * Lists all available sessions.
     * <p>
     * Returns metadata about all sessions that can be resumed, including their IDs,
     * start times, and summaries.
     *
     * @return a future that resolves with a list of session metadata
     * @see SessionMetadata
     * @see #resumeSession(String, com.github.copilot.rpc.ResumeSessionConfig)
     */

View on GitHub (pinned to cd8cf15dc3)