{"record":{"id":"66278489e801ff3e","repo":"nikivdev/code","slug":"device-auth-poll-failed-http","errorCode":null,"errorMessage":"device auth poll failed: HTTP {}","messagePattern":"device auth poll failed: HTTP (.+?)","errorType":"http","errorClass":null,"httpStatus":null,"severity":"error","filePath":"src/auth.rs","lineNumber":83,"sourceCode":"\n    open_in_browser(&payload.verification_url);\n\n    let expires_at = Instant::now() + Duration::from_secs(payload.expires_in);\n    let poll_url = format!(\"{}/api/auth/cli/poll\", api_url);\n\n    println!(\"Waiting for approval...\");\n\n    while Instant::now() < expires_at {\n        sleep(Duration::from_secs(payload.interval.max(1)));\n\n        let poll_response = client\n            .post(&poll_url)\n            .json(&serde_json::json!({\"device_code\": payload.device_code}))\n            .send()\n            .context(\"failed to poll device auth\")?;\n\n        if !poll_response.status().is_success() {\n            bail!(\"device auth poll failed: HTTP {}\", poll_response.status());\n        }\n\n        let poll: DevicePollResponse = poll_response\n            .json()\n            .context(\"failed to parse device auth poll response\")?;\n\n        match poll.status.as_str() {\n            \"approved\" => {\n                let token = poll\n                    .token\n                    .ok_or_else(|| anyhow!(\"device auth approved without token\"))?;\n                env::save_ai_auth_token(token, Some(api_url.clone()))?;\n                println!(\"✓ Auth complete. You're ready to use Flow AI.\");\n                return Ok(());\n            }\n            \"pending\" => continue,\n            \"expired\" => bail!(\"device code expired. Run `f auth` again.\"),\n            \"invalid\" => bail!(\"device code invalid. Run `f auth` again.\"),","sourceCodeStart":65,"sourceCodeEnd":101,"githubUrl":"https://github.com/nikivdev/code/blob/a747e741ae92c09071d0ae946ab48488adcff1ce/src/auth.rs#L65-L101","documentation":"During the device-auth login loop, each poll of the token endpoint must return 2xx. A non-2xx poll response aborts the whole login with this error. Note that OAuth-style 'slow_down'/'authorization_pending' hints are expected as 200-with-status-body in this implementation; an HTTP-level failure here means something is wrong with the request or the service.","triggerScenarios":"POST to poll_url with {\"device_code\": ...} returns 4xx/5xx: device code malformed/expired server-side, wrong poll URL, rate limiting (429), or auth service outage.","commonSituations":"Polling too aggressively triggers 429; network/proxy intermittent failures; device_code corrupted because the start response failed to parse fields; API version mismatch changing the poll endpoint.","solutions":["Check the status code (429 → back off and slow the poll interval; 4xx → re-run 'f auth' for a fresh device code; 5xx → retry after a delay)","Increase the poll interval to respect rate limits before retrying","Re-run the login to obtain a new device code if the current one is rejected","Verify API base URL / endpoint configuration matches the auth server"],"exampleFix":"// before\nif !poll_response.status().is_success() {\n    bail!(\"device auth poll failed: HTTP {}\", poll_response.status());\n}\n// after\nif poll_response.status() == StatusCode::TOO_MANY_REQUESTS {\n    interval = Duration::from_secs(interval.as_secs() * 2);\n    continue;\n}\nif !poll_response.status().is_success() {\n    bail!(\"device auth poll failed: HTTP {}\", poll_response.status());\n}","handlingStrategy":"retry","validationCode":"// Poll with exponential backoff to avoid 429s\nlet mut interval = Duration::from_secs(5);\nloop {\n    std::thread::sleep(interval);\n    interval = (interval * 2).min(Duration::from_secs(30));\n    // ... send poll request\n}","typeGuard":null,"tryCatchPattern":"match login(&api_url) {\n    Err(e) if e.to_string().contains(\"device auth poll failed\") => {\n        eprintln!(\"{}\\nPolling failed; get a new code with `f auth`.\", e);\n    }\n    other => other?,\n}","preventionTips":["Back off on 429 and cap poll frequency","Regenerate the device code via a fresh 'f auth' if the server rejects it","Validate the start response fields before polling","Verify the poll endpoint URL matches the current auth API version"],"tags":["network","http","authentication","polling"],"backgroundTag":"device-auth-flow-failed","analyzedSha":"a747e741ae92c09071d0ae946ab48488adcff1ce","analyzedAt":"2026-09-01T22:43:55.719Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-08T10:18:20.063Z"}