zed-industries/zed · error
Copilot sign-in failed: unexpected response from GitHub
Error message
Copilot sign-in failed: unexpected response from GitHub
What it means
The device-flow token response parsed successfully as JSON but contained neither an access_token nor an error field - the None arm of the match. Zed treats any such shape as 'unexpected response from GitHub' because the OAuth device-grant spec requires one of the two. It almost always indicates a response that is not really the OAuth endpoint's payload (proxy page, outage body) rather than a spec'd error.
Source
Thrown at crates/copilot_chat/src/copilot_oauth.rs:135
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 {
b'A'..=b'Z' | b'a'..=b'z' | b'0'..=b'9' | b'-' | b'_' | b'.' | b'~' => {
encoded.push(byte as char)View on GitHub (pinned to f4178619ac)
Solutions
- Retry the sign-in flow once to rule out a transient body
- Inspect what host actually answered (proxy/enterprise override of the OAuth endpoint)
- For GitHub Enterprise, verify the instance supports the device flow and its version is current
- Bypass the proxy for github.com/login/oauth endpoints and retry
Defensive patterns
Strategy: try-catch
Try / catch
match poll_for_token(/* .. */).await {
Ok(token) => Ok(token),
Err(err) if err.to_string().contains("unexpected response") => {
// retry once with a fresh flow; if it repeats, report proxy/enterprise endpoint issues
retry_sign_in_once().await
}
Err(err) => Err(err),
} Prevention
- Ensure nothing between the client and github.com rewrites OAuth endpoint responses
- For GitHub Enterprise, pin a verified OAuth base URI instead of guessing paths
When it happens
Trigger: Polling https://github.com/login/oauth/access_token returns 200 with a body that is valid JSON yet lacks both access_token and error - e.g. an intercepting proxy returning an empty JSON object, a GitHub incident serving a stub body, or a custom github-enterprise host whose OAuth endpoints are misconfigured.
Common situations: Corporate TLS-inspecting proxies rewriting OAuth responses; GitHub Enterprise Server versions with different device-flow support; transient outage bodies; GITHUB_ENTERPRISE_URI misconfigured to a non-OAuth path.
Related errors
- The Copilot sign-in code expired. Please try again.
- Copilot sign-in was cancelled.
- Copilot sign-in failed: {other}
- unsupported Copilot language server architecture: {architect
- Failed to connect to API: {} {}
AI-assisted analysis of zed-industries/zed@f4178619ac (2026-08-20).
Data as JSON: /api/errors/e59465388ebe351a.
Report an issue: GitHub.