{"record":{"id":"7f6b23cd5f4e8473","repo":"charmbracelet/crush","slug":"failed-to-set-current-session-w","errorCode":null,"errorMessage":"failed to set current session: %w","messagePattern":"failed to set current session: %w","errorType":"error_code","errorClass":null,"httpStatus":null,"severity":"error","filePath":"internal/client/proto.go","lineNumber":104,"sourceCode":"\treturn nil\n}\n\n// SetCurrentSession reports the client's current-session selection\n// for the named workspace. An empty sessionID clears the entry. The\n// request carries the process-scoped client ID minted in [NewClient]\n// as a query parameter so the server can route the update to the\n// correct [clientState] entry.\nfunc (c *Client) SetCurrentSession(ctx context.Context, workspaceID, sessionID string) error {\n\tq := url.Values{\"client_id\": []string{c.clientID}}\n\trsp, err := c.post(\n\t\tctx,\n\t\tfmt.Sprintf(\"/workspaces/%s/current-session\", workspaceID),\n\t\tq,\n\t\tjsonBody(proto.CurrentSession{SessionID: sessionID}),\n\t\thttp.Header{\"Content-Type\": []string{\"application/json\"}},\n\t)\n\tif err != nil {\n\t\treturn fmt.Errorf(\"failed to set current session: %w\", err)\n\t}\n\tdefer rsp.Body.Close()\n\tif err := checkStatus(rsp); err != nil {\n\t\treturn fmt.Errorf(\"failed to set current session: %w\", err)\n\t}\n\treturn nil\n}\n\n// SubscribeEvents subscribes to server-sent events for a workspace.\nfunc (c *Client) SubscribeEvents(ctx context.Context, id string) (<-chan any, error) {\n\tevents := make(chan any, 100)\n\tq := url.Values{\"client_id\": []string{c.clientID}}\n\t//nolint:bodyclose\n\trsp, err := c.get(ctx, fmt.Sprintf(\"/workspaces/%s/events\", id), q, http.Header{\n\t\t\"Accept\":        []string{\"text/event-stream\"},\n\t\t\"Cache-Control\": []string{\"no-cache\"},\n\t\t\"Connection\":    []string{\"keep-alive\"},\n\t})","sourceCodeStart":86,"sourceCodeEnd":122,"githubUrl":"https://github.com/charmbracelet/crush/blob/7944b8e52225d8805e31eacbf7ef24856b0dfb7a/internal/client/proto.go#L86-L122","documentation":"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.","triggerScenarios":"Calling client.SetCurrentSession(ctx, workspaceID, sessionID) when the server is unreachable, connection reset, or ctx is canceled/deadline-exceeded before the POST completes.","commonSituations":"Session switching while the server is shutting down; user cancels (ctrl-c) tearing down the context mid-update; transient network drops; misconfigured server URL.","solutions":["Verify the server is running and the URL is correct.","Check errors.Is(err, context.Canceled): if so, this is expected during shutdown and can be ignored.","Retry the POST with a fresh context if the deadline expired.","Confirm the workspaceID is valid (404s surface via the checkStatus branch instead)."],"exampleFix":"// before\nif err := client.SetCurrentSession(ctx, wsID, sessID); err != nil { return err }\n// after: ignore cancel during shutdown\nif err := client.SetCurrentSession(ctx, wsID, sessID); err != nil {\n    if errors.Is(err, context.Canceled) { return nil }\n    return err\n}","handlingStrategy":"try-catch","validationCode":"if ctx.Err() != nil {\n    return nil // caller already canceling; skip the update\n}","typeGuard":null,"tryCatchPattern":"err := client.SetCurrentSession(ctx, wsID, sessID)\nif err != nil {\n    if errors.Is(err, context.Canceled) || errors.Is(err, context.DeadlineExceeded) {\n        log.Warn(\"current-session update aborted\", \"err\", err)\n        return nil\n    }\n    return err\n}","preventionTips":["Ignore best-effort state updates during shutdown.","Validate ctx before issuing fire-and-forget posts.","Probe server reachability at startup.","Use a dedicated timeout context for state updates."],"tags":["network","http-client","session"],"backgroundTag":"connection-refused","analyzedSha":"7944b8e52225d8805e31eacbf7ef24856b0dfb7a","analyzedAt":"2026-08-29T12:48:59.079Z","schemaVersion":2},"datasetVersion":"2026-08-29T17:17:51.833Z"}