github/copilot-sdk · error · InvalidOperationException
{response.Error ?? "Failed to set foreground session"}
Error message
{response.Error ?? "Failed to set foreground session"} What it means
Thrown when the session.setForeground RPC returns Success=false; the server's response.Error text is used if present, otherwise the generic 'Failed to set foreground session' message. Foreground designation tells the CLI which session receives user input/events, so a false response means the operation was rejected.
Solutions
- Verify the sessionId is a live session created via this client and not yet deleted
- Wrap the call so you can fall back or no-op when the session already ended
- Call SetForegroundSessionAsync immediately after session creation, before any disposal
- Update the Copilot CLI if the server consistently rejects valid sessions
Example fix
// before
await client.SetForegroundSessionAsync(sessionId);
// after
if (!session.IsCompleted)
{
await client.SetForegroundSessionAsync(sessionId);
} Defensive patterns
Strategy: try-catch
Validate before calling
if (!activeSessions.Contains(sessionId)) throw new InvalidOperationException("cannot set foreground on unknown/ended session"); Try / catch
try { await client.SetForegroundSessionAsync(sessionId); }
catch (InvalidOperationException ex) when (ex.Message.Contains("foreground"))
{ logger.LogWarning("foreground switch rejected: {Reason}", ex.Message); } Prevention
- Set foreground right after session creation
- Don't call after session delete/complete
- Keep session lifecycle in one owner component
- Capture and log the server-provided error text
When it happens
Trigger: Calling SetForegroundSessionAsync with a sessionId the server does not recognize, a session that already ended, or when the server refuses the foreground switch for lifecycle reasons.
Common situations: Setting foreground for a session after it completed/errored; using a session ID from another connection; racing session disposal with the foreground call.
Related errors
- Failed to set foreground session
- session.create response did not include a sessionId.
- session.create returned sessionId
- Failed to delete session
- Unknown session
AI-assisted analysis of github/copilot-sdk@cd8cf15dc3 (2026-09-09).
Data as JSON: /api/errors/590f570b2f8a56e8.
Report an issue: GitHub.
Appendix: source
Thrown at dotnet/src/Client.cs:1874
/// <param name="cancellationToken">A token to cancel the operation.</param>
/// <exception cref="InvalidOperationException">Thrown if the operation fails.</exception>
/// <example>
/// <code>
/// await client.SetForegroundSessionIdAsync("session-123");
/// </code>
/// </example>
public async Task SetForegroundSessionIdAsync(string sessionId, CancellationToken cancellationToken = default)
{
ArgumentNullException.ThrowIfNull(sessionId);
var connection = await EnsureConnectedAsync(cancellationToken);
var response = await InvokeRpcAsync<SetForegroundSessionResponse>(
connection.Rpc, "session.setForeground", [new SetForegroundSessionRequest(sessionId)], cancellationToken);
if (!response.Success)
{
throw new InvalidOperationException(response.Error ?? "Failed to set foreground session");
}
}
/// <summary>
/// Subscribes to session lifecycle events of a specific kind.
/// </summary>
/// <typeparam name="T">
/// The lifecycle event type to listen for. Pass a derived type such as
/// <see cref="SessionCreatedEvent"/> to filter by kind, or
/// <see cref="SessionLifecycleEvent"/> to receive every lifecycle event.
/// </typeparam>
/// <param name="handler">A callback invoked when a matching lifecycle event arrives.</param>
/// <returns>An <see cref="IDisposable"/> that, when disposed, unsubscribes the handler.</returns>
/// <example>
/// <code>
/// using var sub = client.OnLifecycle<SessionForegroundEvent>(evt =>
/// {
/// Console.WriteLine($"Session {evt.SessionId} is now in foreground");View on GitHub (pinned to cd8cf15dc3)