tirth8205/code-review-graph · error · RuntimeError

OpenAI API error: {msg}

Error message

OpenAI API error: {msg}

What it means

This RuntimeError fires when the HTTP request to the OpenAI-compatible embeddings endpoint succeeded (status 200) but the JSON response body contains a top-level "error" object — some gateways report errors in-band rather than via HTTP status. The provider extracts error.message (or stringifies the error) and raises.

Source

Thrown at code_review_graph/embeddings.py:516

                            err_obj = parsed["error"]
                            err_msg = (
                                err_obj.get("message", err_msg)
                                if isinstance(err_obj, dict) else str(err_obj)
                            )
                    except Exception:  # nosec B110
                        # Non-JSON error body is fine: we already seeded
                        # err_msg with the raw body above, so fall through.
                        pass
                    raise RuntimeError(
                        f"OpenAI API HTTP {http_err.code}: {err_msg}"
                    ) from http_err

                response = _json.loads(raw)

                if "error" in response:
                    err = response["error"]
                    msg = err.get("message", "unknown") if isinstance(err, dict) else str(err)
                    raise RuntimeError(f"OpenAI API error: {msg}")

                data = response.get("data", [])
                if not data:
                    raise RuntimeError("OpenAI API returned empty data")
                # OpenAI spec: data[i].index maps to input[i], but some
                # compatible gateways re-order results or drop entries on
                # partial failure, and others omit `index` entirely. Three
                # disjoint cases:
                #   1. All items have a valid int ``index``: must form a
                #      permutation of 0..N-1, then sort and use.
                #   2. NO item carries an ``index`` field: trust server
                #      order, only verify count matches.
                #   3. Anything in between (partial indices, str indices,
                #      missing on some): refuse. Zipping server order in
                #      that case would happily misalign the indexed items.
                any_has_index = any("index" in item for item in data)
                all_int_index = all(
                    isinstance(item.get("index"), int) for item in data

View on GitHub (pinned to b58668751a)

Solutions

  1. Inspect the embedded message to identify the underlying cause (quota, model access, upstream failure)
  2. If using a proxy/router, check its logs and upstream provider configuration
  3. Verify the model name is allowed for your key/gateway
  4. Retry with backoff if the message indicates a transient upstream issue
Defensive patterns

Strategy: try-catch

Validate before calling

# Smoke-test the gateway: some return 200 with in-band errors
provider.embed_query("ping")  # fail fast before a long batch

Try / catch

try:
    vecs = provider.embed(texts)
except RuntimeError as e:
    if "OpenAI API error:" in str(e):
        log_gateway_incident(str(e))  # in-band gateway failure
    raise

Prevention

When it happens

Trigger: embed()/embed_query() receiving a 200 response whose body is {"error": {...}} — typical of OpenAI-compatible proxies, LiteLLM routers, orAzure-style endpoints that wrap upstream failures in-band.

Common situations: Self-hosted or proxied OpenAI-compatible gateways that return 200 with an error payload for quota, model-access, or upstream-provider failures; upstream OpenAI outages surfaced through a router.

Related errors


AI-assisted analysis of tirth8205/code-review-graph@b58668751a (2026-08-28). Data as JSON: /api/errors/dbf491fcdcaef383. Report an issue: GitHub.