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
- Read the HTTP code and embedded message: 401 → fix VOYAGE_API_KEY; 400 → check model/input types; 429 → back off; 5xx → retry later
- Verify the model name and input_type parameters are valid for the Voyage API version you target
- Split large batches to stay under Voyage's token-per-request limit
- 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
- Validate the Voyage model name against current API docs (models deprecate)
- Batch under Voyage's token-per-request limit; split very long documents
- Cache embeddings so rate-limit retries don't re-embed the whole corpus
- Backoff with jitter on 429; alert on persistent 5xx
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
- OpenAI API HTTP {http_err.code}: {err_msg}
- MiniMax API error: {base_resp.get('status_msg', 'unknown')}
- OpenAI API error: {msg}
- Voyage API error: {msg}
- sentence-transformers not installed. Run: pip install code-r
AI-assisted analysis of tirth8205/code-review-graph@b58668751a (2026-08-28).
Data as JSON: /api/errors/9a3e05c06f74335f.
Report an issue: GitHub.