charmbracelet/crush · error

failed to set current session: %w

Error message

failed to set current session: %w

What it means

SetCurrentSession wraps an error from the underlying c.post transport call for POST /workspaces/{workspaceID}/current-session?client_id=... . Raised before status checking, it indicates the request failed at the network layer or the context was canceled. The wrapped cause is preserved for errors.Is/As inspection.

Source

Thrown at internal/client/proto.go:104

	return nil
}

// SetCurrentSession reports the client's current-session selection
// for the named workspace. An empty sessionID clears the entry. The
// request carries the process-scoped client ID minted in [NewClient]
// as a query parameter so the server can route the update to the
// correct [clientState] entry.
func (c *Client) SetCurrentSession(ctx context.Context, workspaceID, sessionID string) error {
	q := url.Values{"client_id": []string{c.clientID}}
	rsp, err := c.post(
		ctx,
		fmt.Sprintf("/workspaces/%s/current-session", workspaceID),
		q,
		jsonBody(proto.CurrentSession{SessionID: sessionID}),
		http.Header{"Content-Type": []string{"application/json"}},
	)
	if err != nil {
		return fmt.Errorf("failed to set current session: %w", err)
	}
	defer rsp.Body.Close()
	if err := checkStatus(rsp); err != nil {
		return fmt.Errorf("failed to set current session: %w", err)
	}
	return nil
}

// SubscribeEvents subscribes to server-sent events for a workspace.
func (c *Client) SubscribeEvents(ctx context.Context, id string) (<-chan any, error) {
	events := make(chan any, 100)
	q := url.Values{"client_id": []string{c.clientID}}
	//nolint:bodyclose
	rsp, err := c.get(ctx, fmt.Sprintf("/workspaces/%s/events", id), q, http.Header{
		"Accept":        []string{"text/event-stream"},
		"Cache-Control": []string{"no-cache"},
		"Connection":    []string{"keep-alive"},
	})

View on GitHub (pinned to 7944b8e522)

Solutions

  1. Verify the server is running and the URL is correct.
  2. Check errors.Is(err, context.Canceled): if so, this is expected during shutdown and can be ignored.
  3. Retry the POST with a fresh context if the deadline expired.
  4. Confirm the workspaceID is valid (404s surface via the checkStatus branch instead).

Example fix

// before
if err := client.SetCurrentSession(ctx, wsID, sessID); err != nil { return err }
// after: ignore cancel during shutdown
if err := client.SetCurrentSession(ctx, wsID, sessID); err != nil {
    if errors.Is(err, context.Canceled) { return nil }
    return err
}
Defensive patterns

Strategy: try-catch

Validate before calling

if ctx.Err() != nil {
    return nil // caller already canceling; skip the update
}

Try / catch

err := client.SetCurrentSession(ctx, wsID, sessID)
if err != nil {
    if errors.Is(err, context.Canceled) || errors.Is(err, context.DeadlineExceeded) {
        log.Warn("current-session update aborted", "err", err)
        return nil
    }
    return err
}

Prevention

When it happens

Trigger: Calling client.SetCurrentSession(ctx, workspaceID, sessionID) when the server is unreachable, connection reset, or ctx is canceled/deadline-exceeded before the POST completes.

Common situations: Session switching while the server is shutting down; user cancels (ctrl-c) tearing down the context mid-update; transient network drops; misconfigured server URL.

Related errors


AI-assisted analysis of charmbracelet/crush@7944b8e522 (2026-08-29). Data as JSON: /api/errors/7f6b23cd5f4e8473. Report an issue: GitHub.