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

  1. Check the server logs — logger.exception('Copilot endpoint provisioning failed') captured the full traceback with the real cause.
  2. Confirm the account actually has a Copilot subscription or org seat before retrying login.
  3. If using enterprise, verify the enterprise_url produces a valid Copilot base (copilot.enterprise_base) and that Copilot is enabled on the instance.
  4. 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

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


AI-assisted analysis of odysseus-dev/odysseus@f9235ebbf1 (2026-08-14). Data as JSON: /api/errors/6916452b2cbd3904. Report an issue: GitHub.