odysseus-dev/odysseus · error · HTTPException
GitHub device-code request failed: {e}
Error message
GitHub device-code request failed: {e} What it means
Raised (HTTP 502) by the Copilot device-flow start helper when copilot.request_device_code(host) fails with any non-HTTPStatusError exception. This is the catch-all branch: network-level failures (DNS failure, connection refused, TLS error, timeout) and unexpected client bugs all land here, with the exception text appended to the message. It means the device-code request never got a usable HTTP response from GitHub / the enterprise host.
Source
Thrown at routes/copilot_routes.py:113
from routes.model_routes import _invalidate_models_cache
_invalidate_models_cache()
except Exception:
pass
return result
def _start_device_flow(request: Request, form) -> DeviceFlowStart:
host = copilot.GITHUB_HOST
ent = str(form.get("enterprise_url") or "").strip()
if ent:
host = copilot.normalize_domain(ent)
try:
data = copilot.request_device_code(host)
except httpx.HTTPStatusError as e:
status = e.response.status_code if e.response is not None else "unknown"
raise HTTPException(502, f"GitHub device-code request failed (HTTP {status})")
except Exception as e:
raise HTTPException(502, f"GitHub device-code request failed: {e}")
device_code = data.get("device_code")
if not device_code:
raise HTTPException(502, "GitHub did not return a device code")
# verification_uri_complete embeds the user code, so the browser tab we
# open lands the user straight on GitHub's "Authorize" screen with the
# code pre-filled — one click, no manual code entry.
return DeviceFlowStart(
pending={
"device_code": device_code,
"host": host,
"enterprise_url": ent,
"owner": get_current_user(request) or None,
},
response={
"user_code": data.get("user_code"),
"verification_uri": data.get("verification_uri"),View on GitHub (pinned to f9235ebbf1)
Solutions
- Read the appended exception text: 'connection refused'/'name or service not known' points to DNS/network, timeouts point to firewall/proxy.
- Verify outbound HTTPS from the server: curl -sS https://github.com/login/device/code -o /dev/null -w '%{http_code}'.
- Configure the proxy environment (HTTP_PROXY/HTTPS_PROXY/NO_PROXY) the app's httpx client honors if the network requires one.
- For enterprise hosts, confirm the domain resolves and serves a valid certificate.
Defensive patterns
Strategy: retry
Validate before calling
// Verify outbound connectivity from the server before offering Copilot login
// curl -sS -o /dev/null -w '%{http_code}' https://github.com/login/device/code (expect non-000) Try / catch
try { start = await post('/copilot/device/start', form); } catch (e) { if (e.status === 502) { const cause = e.message.split(': ').pop(); if (/timed? ?out|connect|resolve/i.test(cause)) showBanner('Server cannot reach GitHub — check proxy/firewall.'); } throw e; } Prevention
- Configure HTTP_PROXY/HTTPS_PROXY for environments that require an egress proxy.
- Smoke-test outbound HTTPS from the server host as part of deployment checks.
When it happens
Trigger: Starting Copilot device login while the server has no outbound internet access (air-gapped or proxied environment); DNS for github.com or the enterprise domain fails; a self-signed/enterprise TLS intercept breaks the handshake; the request exceeds the httpx timeout.
Common situations: Homelab or corporate network behind a mandatory proxy that is not configured for httpx; typo'd enterprise domain that does not resolve; firewall blocking outbound 443; transient network drop during login start.
Related errors
- GitHub device-code request failed (HTTP {status})
- GitHub did not return a device code
- Request failed (HTTP ${response.status})
- Unknown device-flow provider: ${provider}
- ${cfg.label} sign-in did not return a poll id
AI-assisted analysis of odysseus-dev/odysseus@f9235ebbf1 (2026-08-14).
Data as JSON: /api/errors/eaeb69d6dcc1b39a.
Report an issue: GitHub.