odysseus-dev/odysseus · error · HTTPException
Login succeeded but provisioning failed: {e}
Error message
Login succeeded but provisioning failed: {e} What it means
Raised (HTTP 500) during Copilot device-flow polling after the OAuth half succeeded: poll_access_token returned a valid access_token, but _provision_endpoint(token, base, owner) — which registers/activates the Copilot chat completion endpoint for that user — threw an exception. The GitHub login itself worked; only the follow-up provisioning against the Copilot API (COPILOT_BASE or the enterprise base) failed. The underlying exception is logged via logger.exception before the 500 is raised.
Source
Thrown at routes/copilot_routes.py:152
interval=int(data.get("interval") or 5),
expires_in=int(data.get("expires_in") or 900),
)
def _poll_device_flow(_request: Request, pending: Dict) -> DeviceFlowPoll:
try:
data = copilot.poll_access_token(pending["host"], pending["device_code"])
except Exception as e:
return DeviceFlowPoll.pending(f"poll error: {e}")
token = data.get("access_token")
if token:
base = copilot.enterprise_base(pending["enterprise_url"]) if pending["enterprise_url"] else copilot.COPILOT_BASE
try:
result = _provision_endpoint(token, base, pending["owner"])
except Exception as e:
logger.exception("Copilot endpoint provisioning failed")
raise HTTPException(500, f"Login succeeded but provisioning failed: {e}")
return DeviceFlowPoll.authorized(result)
err = data.get("error")
if err == "authorization_pending":
return DeviceFlowPoll.pending()
if err == "slow_down":
return DeviceFlowPoll.slow_down(int(data.get("interval") or 0) or None)
if err in ("expired_token", "access_denied"):
return DeviceFlowPoll.failed(err)
# Unknown error — surface but keep the session for another try.
return DeviceFlowPoll.pending(err or "unknown")
def setup_copilot_routes():
return create_device_flow_router(
prefix="/api/copilot",
tags=["copilot"],
store=_DEVICE_FLOW_STORE,View on GitHub (pinned to f9235ebbf1)
Solutions
- Check the server logs — logger.exception('Copilot endpoint provisioning failed') captured the full traceback with the real cause.
- Confirm the account actually has a Copilot subscription or org seat before retrying login.
- If using enterprise, verify the enterprise_url produces a valid Copilot base (copilot.enterprise_base) and that Copilot is enabled on the instance.
- Retry the login once the Copilot service is healthy — the token itself was fine, only provisioning failed.
Defensive patterns
Strategy: try-catch
Try / catch
try { poll = await post('/copilot/device/poll', { poll_id }); } catch (e) { if (e.status === 500 && /provisioning failed/.test(e.message)) { showBanner('GitHub login worked but Copilot provisioning failed — verify your Copilot subscription and retry.'); return stopPolling(); } throw e; } Prevention
- Confirm the account has a Copilot seat before starting device login.
- Check server logs for the 'Copilot endpoint provisioning failed' traceback whenever this 500 appears.
When it happens
Trigger: Device poll succeeds in getting a token, then the provisioning call to the Copilot endpoint fails: user has no Copilot subscription/seat (403 from the Copilot API), Copilot service outage, enterprise base URL misconfigured, network failure reaching api.githubcopilot.com.
Common situations: User authenticates with a GitHub account that has no Copilot access (no subscription, no org seat); GHES Copilot integration not enabled so the enterprise base 404s; transient Copilot API outage right at login time.
Related errors
- GitHub device-code request failed (HTTP {status})
- GitHub device-code request failed: {e}
- GitHub did not return a device code
- Request failed (HTTP ${response.status})
- Unknown device-flow provider: ${provider}
AI-assisted analysis of odysseus-dev/odysseus@f9235ebbf1 (2026-08-14).
Data as JSON: /api/errors/6916452b2cbd3904.
Report an issue: GitHub.