tirth8205/code-review-graph · error · RuntimeError

Voyage API HTTP {http_err.code}: {err_msg}

Error message

Voyage API HTTP {http_err.code}: {err_msg}

What it means

The Voyage embeddings provider raises this RuntimeError when the HTTPS request to the Voyage API returns an HTTPError. It attempts to parse the error body as JSON to extract a message (falling back to the raw body), then raises with the HTTP code and chains the original http_err — e.g. 'Voyage API HTTP 401: invalid api key'.

Source

Thrown at code_review_graph/embeddings.py:733

                except urllib.error.HTTPError as http_err:
                    if http_err.code == 429 or 500 <= http_err.code < 600:
                        raise
                    try:
                        err_body = http_err.read().decode("utf-8", errors="replace")
                    except Exception:
                        err_body = ""
                    err_msg = err_body or str(http_err)
                    try:
                        parsed = _json.loads(err_body)
                        if isinstance(parsed, dict) and "error" in parsed:
                            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
                        pass
                    raise RuntimeError(
                        f"Voyage 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"Voyage API error: {msg}")

                data = response.get("data", [])
                if not data:
                    raise RuntimeError("Voyage API returned empty data")

                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. Read the HTTP code and embedded message: 401 → fix VOYAGE_API_KEY; 400 → check model/input types; 429 → back off; 5xx → retry later
  2. Verify the model name and input_type parameters are valid for the Voyage API version you target
  3. Split large batches to stay under Voyage's token-per-request limit
  4. Add exponential-backoff retry around 429/5xx responses
Defensive patterns

Strategy: retry

Validate before calling

import os
assert os.environ.get("VOYAGE_API_KEY"), "VOYAGE_API_KEY not set"
provider.embed_query("ping")  # smoke-test key+model before bulk run

Try / catch

import time
for attempt in range(5):
    try:
        return provider.embed(texts)
    except RuntimeError as e:
        s = str(e)
        if "Voyage API HTTP 429" in s or "HTTP 5" in s:
            time.sleep(2 ** attempt); continue
        raise  # 401/400 need credential/model fixes, not retries

Prevention

When it happens

Trigger: embed()/embed_query() hitting a 401 (invalid VOYAGE_API_KEY), 400 (bad model or input type), 429 (rate limit), or 5xx from api.voyageai.com.

Common situations: Missing/expired Voyage API key, typo'd voyage model name (e.g. voyage-3 vs voyage-2), exceeding Voyage's per-request token/batch limits, or rate limiting during large indexing runs.

Understand the failure class

Background: "API error: {status}" and "HTTP 401/403/404/429/5xx" errors: non-2xx HTTP responses explained — this error's family across 27 libraries.

Related errors


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