github/copilot-sdk · error

failed to unmarshal setForeground response

Error message

failed to unmarshal setForeground response: %w

What it means

Returned by Client.SetForegroundSessionID when the session.setForeground RPC succeeds but its JSON result cannot be decoded into setForegroundSessionResponse; the json.Unmarshal error is wrapped via %w. It signals that the CLI returned an unexpected response shape, typically a client/CLI version mismatch.

Solutions

  1. Log the raw result to see the returned payload
  2. Confirm the TUI is running and supports foreground switching
  3. Update client library and backend to the same version
  4. Retry after confirming the TUI state

Example fix

// before
err := client.SetForegroundSessionID(ctx, id)
// after
if err := client.SetForegroundSessionID(ctx, id); err != nil {
    if strings.Contains(err.Error(), "setForeground response") {
        log.Printf("unexpected ack from backend: %v", err)
    }
    return err
}
Defensive patterns

Strategy: try-catch

Validate before calling

if targetSessionID == "" {
    return fmt.Errorf("SetForegroundSessionID: empty sessionID")
}

Type guard

func isSetForegroundUnmarshalError(err error) bool {
    return strings.Contains(err.Error(), "setForeground response")
}

Try / catch

if err := client.SetForegroundSessionID(ctx, id); err != nil {
    if isSetForegroundUnmarshalError(err) {
        // ack shape unexpected: verify TUI running, retry
        return fmt.Errorf("setForeground ack undecodable: %w", err)
    }
    return err
}

Prevention

When it happens

Trigger: Calling SetForegroundSessionID when the backend's response is not the expected {success, error} JSON object.

Common situations: Backend version drift; TUI not running so the backend returns an error string instead of the ack object; IPC stream corruption.

Understand the failure class

Background: "failed to unmarshal" / json.Unmarshal errors: why parsing a response into a Go struct fails and how to fix it — this error's family across 23 libraries.

Related errors


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

Appendix: source

Thrown at go/client.go:1729

//
// Example:
//
//	if err := client.SetForegroundSessionID("session-123"); err != nil {
//	    log.Fatal(err)
//	}
func (c *Client) SetForegroundSessionID(ctx context.Context, sessionID string) error {
	if err := c.ensureConnected(ctx); err != nil {
		return err
	}

	result, err := c.client.Request(ctx, "session.setForeground", setForegroundSessionRequest{SessionID: sessionID})
	if err != nil {
		return err
	}

	var response setForegroundSessionResponse
	if err := json.Unmarshal(result, &response); err != nil {
		return fmt.Errorf("failed to unmarshal setForeground response: %w", err)
	}

	if !response.Success {
		errorMsg := "unknown error"
		if response.Error != nil {
			errorMsg = *response.Error
		}
		return fmt.Errorf("failed to set foreground session: %s", errorMsg)
	}

	return nil
}

// On subscribes to all session lifecycle events.
//
// Lifecycle events are emitted when sessions are created, deleted, updated,
// or change foreground/background state (in TUI+server mode).
//

View on GitHub (pinned to cd8cf15dc3)