{"record":{"id":"f984497fb89607c2","repo":"zed-industries/zed","slug":"the-copilot-sign-in-code-expired-please-try-again","errorCode":null,"errorMessage":"The Copilot sign-in code expired. Please try again.","messagePattern":"The Copilot sign-in code expired\\. Please try again\\.","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"crates/copilot_chat/src/copilot_oauth.rs","lineNumber":132,"sourceCode":"            .header(\"Content-Type\", \"application/x-www-form-urlencoded\")\n            .body(AsyncBody::from(body.clone()))?;\n\n        let mut response = client.send(request).await?;\n        let mut response_body = Vec::new();\n        response.body_mut().read_to_end(&mut response_body).await?;\n\n        let parsed: AccessTokenResponse = serde_json::from_slice(&response_body)\n            .context(\"Failed to parse GitHub access-token response\")?;\n\n        if let Some(token) = parsed.access_token {\n            return Ok(token);\n        }\n\n        match parsed.error.as_deref() {\n            Some(\"authorization_pending\") => continue,\n            // GitHub asks us to back off; increase the interval and keep polling.\n            Some(\"slow_down\") => interval += 5,\n            Some(\"expired_token\") => bail!(\"The Copilot sign-in code expired. Please try again.\"),\n            Some(\"access_denied\") => bail!(\"Copilot sign-in was cancelled.\"),\n            Some(other) => bail!(\"Copilot sign-in failed: {other}\"),\n            None => bail!(\"Copilot sign-in failed: unexpected response from GitHub\"),\n        }\n    }\n}\n\nfn form_encode(fields: &[(&str, &str)]) -> String {\n    fields\n        .iter()\n        .map(|(key, value)| format!(\"{}={}\", url_encode(key), url_encode(value)))\n        .collect::<Vec<_>>()\n        .join(\"&\")\n}\n\nfn url_encode(value: &str) -> String {\n    let mut encoded = String::with_capacity(value.len());\n    for byte in value.bytes() {","sourceCodeStart":114,"sourceCodeEnd":150,"githubUrl":"https://github.com/zed-industries/zed/blob/f4178619acd0d47ea1f76a2025c42962c6d6638c/crates/copilot_chat/src/copilot_oauth.rs#L114-L150","documentation":"Part of Zed's GitHub OAuth device-code flow (copilot_oauth.rs): after the user is shown a code at github.com/login/device, Zed polls the access-token endpoint; GitHub's error field 'expired_token' maps to this bail. GitHub device codes are valid for a short window (typically 15 minutes), after which the flow must be restarted from a new device code.","triggerScenarios":"The polling loop receives error='expired_token': more than the validity window elapsed between displaying the user code and the user completing authorization, or polling was paused (machine slept, process suspended) past expiry.","commonSituations":"User leaves the sign-in dialog open and comes back later; laptop sleep during sign-in; user copies the code but completes verification too late.","solutions":["Restart the Copilot sign-in flow to obtain a fresh device code","Complete authorization at github.com/login/device promptly after the code is displayed","Keep the machine/network awake during sign-in"],"exampleFix":null,"handlingStrategy":"retry","validationCode":"// Fail with a clearer message before GitHub does: device codes live ~15 min\nlet flow_started = std::time::Instant::now();\nif flow_started.elapsed() > Duration::from_secs(14 * 60) {\n    anyhow::bail!(\"sign-in window nearly expired; restart the flow\");\n}","typeGuard":null,"tryCatchPattern":"match poll_for_token(/* .. */).await {\n    Ok(token) => { /* signed in */ }\n    Err(err) if err.to_string().contains(\"expired\") => {\n        // restart device flow from scratch with a new code\n    }\n    Err(err) => return Err(err),\n}","preventionTips":["Show the expiry window next to the device code so users hurry","Restart the whole flow (new device code) on retry - a dead code can never be revived","Avoid machine sleep or long awaits between starting the flow and user authorization"],"tags":["copilot","oauth","device-flow","github","authentication","rust"],"backgroundTag":"oauth-device-code-expired","analyzedSha":"f4178619acd0d47ea1f76a2025c42962c6d6638c","analyzedAt":"2026-08-20T19:29:52.058Z","schemaVersion":2},"datasetVersion":"2026-08-24T22:17:12.610Z"}