zed-industries/zed · warning
Copilot sign-in was cancelled.
Error message
Copilot sign-in was cancelled.
What it means
GitHub's device-flow token endpoint returned error='access_denied', which Zed translates to 'Copilot sign-in was cancelled.' This means the authorization request was actively denied rather than expired - most commonly the user clicked 'Cancel' on GitHub's consent screen, or an org's OAuth policy blocked the app.
Source
Thrown at crates/copilot_chat/src/copilot_oauth.rs:133
.body(AsyncBody::from(body.clone()))?;
let mut response = client.send(request).await?;
let mut response_body = Vec::new();
response.body_mut().read_to_end(&mut response_body).await?;
let parsed: AccessTokenResponse = serde_json::from_slice(&response_body)
.context("Failed to parse GitHub access-token response")?;
if let Some(token) = parsed.access_token {
return Ok(token);
}
match parsed.error.as_deref() {
Some("authorization_pending") => continue,
// GitHub asks us to back off; increase the interval and keep polling.
Some("slow_down") => interval += 5,
Some("expired_token") => bail!("The Copilot sign-in code expired. Please try again."),
Some("access_denied") => bail!("Copilot sign-in was cancelled."),
Some(other) => bail!("Copilot sign-in failed: {other}"),
None => bail!("Copilot sign-in failed: unexpected response from GitHub"),
}
}
}
fn form_encode(fields: &[(&str, &str)]) -> String {
fields
.iter()
.map(|(key, value)| format!("{}={}", url_encode(key), url_encode(value)))
.collect::<Vec<_>>()
.join("&")
}
fn url_encode(value: &str) -> String {
let mut encoded = String::with_capacity(value.len());
for byte in value.bytes() {
match byte {View on GitHub (pinned to f4178619ac)
Solutions
- Restart sign-in and approve the GitHub Copilot OAuth app when prompted
- If on an org account: ask an org owner to approve/allow the Copilot OAuth application
- Check github.com/settings/applications for a previously denied state
Defensive patterns
Strategy: try-catch
Try / catch
match poll_for_token(/* .. */).await {
Ok(token) => Ok(token),
Err(err) if err.to_string().contains("cancelled") => {
// user-denied: return a non-error UI state prompting retry, not a crash
Ok(None)
}
Err(err) => Err(err),
} Prevention
- Treat access_denied as a user choice: show a friendly retry prompt, never a generic failure
- If org OAuth policies block the app, surface that hint when the denial repeats
When it happens
Trigger: Polling receives access_denied after the user rejects the Copilot OAuth app authorization on github.com, cancels the consent prompt, or the GitHub organization restricts third-party OAuth apps so consent auto-denies.
Common situations: Users clicking through GitHub consent screens too quickly; org-managed accounts with OAuth app allow-lists; re-trying sign-in after previously denying and expecting it to succeed without re-consent.
Related errors
- The Copilot sign-in code expired. Please try again.
- Copilot sign-in failed: {other}
- Copilot sign-in failed: unexpected response from GitHub
- Cannot list directory because its path matches the user's wo
- Cannot list directory because its path matches the user's wo
AI-assisted analysis of zed-industries/zed@f4178619ac (2026-08-20).
Data as JSON: /api/errors/f57a6b95c764b9cb.
Report an issue: GitHub.