{"record":{"id":"c0a62b2cbdf3b72b","repo":"xai-org/grok-build","slug":"authentication-cancelled","errorCode":null,"errorMessage":"Authentication cancelled","messagePattern":"Authentication cancelled","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"info","filePath":"crates/codegen/xai-grok-shell/src/agent/mvp_agent/acp_agent.rs","lineNumber":820,"sourceCode":"                let auth_result = if !auth_meta.headless {\n                    let (url_tx, url_rx) = tokio::sync::oneshot::channel();\n                    let (code_tx, code_rx) = tokio::sync::mpsc::channel(1);\n                    let (cancel, _guard) = self\n                        .interactive_auth\n                        .begin(\n                            Some(\n                                crate::auth::single_flight::AttemptChannels::new(\n                                    code_tx,\n                                    url_rx,\n                                ),\n                            ),\n                            client_seq,\n                        );\n                    tokio::select! {\n                        biased;\n                        _ = cancel.cancelled() => {\n                            cancelled = true;\n                            Err(anyhow::anyhow!(\"Authentication cancelled\"))\n                        }\n                        r = crate::auth::run_auth_flow_with_stderr_bridge(\n                            &self.auth_manager,\n                            grok_ctx,\n                            crate::auth::AuthChannels {\n                                url_tx: Some(url_tx),\n                                code_rx,\n                            },\n                            auth_meta.reauth,\n                            auth_meta.force_interactive,\n                            login_override,\n                        ) => r,\n                    }\n                } else {\n                    let (cancel, _guard) = self.interactive_auth.begin(None, client_seq);\n                    tokio::select! {\n                        biased;\n                        _ = cancel.cancelled() => {","sourceCodeStart":802,"sourceCodeEnd":838,"githubUrl":"https://github.com/xai-org/grok-build/blob/bc7f02eddd3d84085849dc19ed216f11c23b0571/crates/codegen/xai-grok-shell/src/agent/mvp_agent/acp_agent.rs#L802-L838","documentation":"This error is thrown in the ACP agent's `authenticate` flow when the interactive authentication request is cancelled while awaiting the auth flow. The agent runs the auth flow (`run_auth_flow_with_stderr_bridge`) inside a `tokio::select!` alongside a cancellation token obtained from `interactive_auth.begin`; when the cancellation future fires first, the code sets `cancelled = true` and returns this anyhow error instead of the auth result. It is a deliberate control-flow signal, not a protocol or credential failure — it means the client (or a timeout/shutdown) aborted authentication before it completed.","triggerScenarios":"Calling the ACP `authenticate` RPC with an `interactive_auth` session and issuing a cancel (client aborts the request, disconnects, or a supervisor cancels the task) while `run_auth_flow_with_stderr_bridge` is still waiting on the browser/URL-based auth flow.","commonSituations":"User closes the auth browser window or presses Ctrl-C on the client before completing OAuth; IDE/ACP client times out a slow auth request; the agent task is cancelled during shutdown while authentication is pending; a second auth request supersedes an in-flight one and cancels the first session.","solutions":["Have the caller treat 'Authentication cancelled' as an expected, benign outcome (map it to a cancelled/aborted RPC status rather than a hard failure) and simply re-issue `authenticate` when the user is ready to log in","Check the client side for premature aborts: raise the client-side timeout for the auth request and ensure the transport is not closed while the auth flow is in flight","Avoid issuing a second `authenticate` call while one is pending; cancel the first deliberately or wait for it to finish","If auth hangs indefinitely, verify the auth flow can reach its URL/redirect handler (network, browser availability) so it completes before anything cancels it"],"exampleFix":"// before\nmatch agent.authenticate(method).await {\n    Err(e) if e.to_string().contains(\"Authentication cancelled\") => panic!(\"auth failed: {e}\"),\n    r => r?,\n}\n// after\nmatch agent.authenticate(method).await {\n    Err(e) if e.to_string().contains(\"Authentication cancelled\") => {\n        tracing::info!(\"auth cancelled by client; retry when user initiates login\");\n        return Ok(()); // benign cancellation, not an auth failure\n    }\n    r => r?,\n}","handlingStrategy":"try-catch","validationCode":null,"typeGuard":null,"tryCatchPattern":"match agent.authenticate(method).await {\n    Err(e) if e.to_string().contains(\"Authentication cancelled\") => {\n        // expected cancellation — surface as user-aborted, retry on demand\n        return Err(AuthError::Cancelled);\n    }\n    Err(e) => return Err(AuthError::Other(e)),\n    Ok(method) => Ok(method),\n}","preventionTips":["Do not abort the authenticate request while the browser/interactive OAuth flow is pending; allow generous client-side timeouts","Serialize authentication attempts — cancel an in-flight one only deliberately","Check transport stability (client disconnects during login cause this cancellation)","Treat this message as a benign control-flow signal in error mapping/telemetry"],"tags":["authentication","cancellation","tokio","async"],"backgroundTag":"operation-cancelled","analyzedSha":"bc7f02eddd3d84085849dc19ed216f11c23b0571","analyzedAt":"2026-08-31T04:59:42.031Z","schemaVersion":2},"datasetVersion":"2026-08-31T09:17:48.483Z"}