odysseus-dev/odysseus · error · HTTPException

Could not resolve endpoint credentials

Error message

Could not resolve endpoint credentials

What it means

HTTP 500 from POST /v1/chat Case 3: the selected ModelEndpoint has a provider_auth_id, and resolve_endpoint_runtime(ep, owner=token_owner) raised while exchanging stored provider credentials for a live base_url + api_key. The bare except hides the cause (expired/revoked OAuth refresh token, missing provider auth record, upstream IdP failure), surfacing only 'Could not resolve endpoint credentials'.

Source

Thrown at routes/webhook/webhook_routes.py:337

            finally:
                db.close()

            if not ep:
                raise HTTPException(400,
                    "No session, api_key, or configured endpoints. "
                    "Pass api_key + model, or configure an endpoint in Admin.")

            base_url = normalize_base(ep.base_url)
            endpoint_url = build_chat_url(base_url)
            model = body.model or "auto"
            api_key = ep.api_key
            if getattr(ep, "provider_auth_id", None):
                try:
                    from src.endpoint_resolver import resolve_endpoint_runtime
                    base_url, api_key = resolve_endpoint_runtime(ep, owner=token_owner)
                    endpoint_url = build_chat_url(base_url)
                except Exception:
                    raise HTTPException(500, "Could not resolve endpoint credentials")

            if model == "auto":
                try:
                    async with httpx.AsyncClient(timeout=5) as client:
                        models_url = build_models_url(base_url)
                        hdrs = build_headers(api_key, base_url)
                        if models_url:
                            resp = await client.get(models_url, headers=hdrs)
                            resp.raise_for_status()
                            data = resp.json()
                            items = data if isinstance(data, list) else (data.get("data") or [])
                            ids = [m.get("id") for m in items if isinstance(m, dict) and m.get("id")]
                            if not ids and isinstance(data, dict):
                                ids = [
                                    m.get("name") or m.get("model")
                                    for m in (data.get("models") or [])
                                    if m.get("name") or m.get("model")
                                ]

View on GitHub (pinned to f9235ebbf1)

Solutions

  1. Re-authorize the provider in Admin (refresh the provider auth) and retry
  2. Check that the endpoint's provider_auth_id points to an existing, valid provider-auth record
  3. As a workaround, replace the provider-auth-backed endpoint with a plain base_url + api_key endpoint
  4. Inspect server logs around the 500 for the swallowed underlying exception
Defensive patterns

Strategy: fallback

Try / catch

if resp.status_code == 500 and 'resolve endpoint credentials' in detail:
    # fall back to a plain api_key ModelEndpoint, and page admin to re-auth the provider
    switch_to_static_key_endpoint()

Prevention

When it happens

Trigger: An endpoint bound to a provider OAuth whose refresh token expired or was revoked; the provider_auth row deleted but the endpoint still references it; token_owner lacking access to the provider auth; provider auth server unreachable.

Common situations: Google/Azure-style provider OAuths that expire after weeks; re-authenticating the provider in Admin but the endpoint keeps a stale reference; sandbox environments with no network path to the IdP.

Related errors


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