{"record":{"id":"9a3e05c06f74335f","repo":"tirth8205/code-review-graph","slug":"voyage-api-http-http-err-code-err-msg","errorCode":null,"errorMessage":"Voyage API HTTP {http_err.code}: {err_msg}","messagePattern":"Voyage API HTTP (.+?): (.+?)","errorType":"http","errorClass":"RuntimeError","httpStatus":null,"severity":"error","filePath":"code_review_graph/embeddings.py","lineNumber":733,"sourceCode":"                except urllib.error.HTTPError as http_err:\n                    if http_err.code == 429 or 500 <= http_err.code < 600:\n                        raise\n                    try:\n                        err_body = http_err.read().decode(\"utf-8\", errors=\"replace\")\n                    except Exception:\n                        err_body = \"\"\n                    err_msg = err_body or str(http_err)\n                    try:\n                        parsed = _json.loads(err_body)\n                        if isinstance(parsed, dict) and \"error\" in parsed:\n                            err_obj = parsed[\"error\"]\n                            err_msg = (\n                                err_obj.get(\"message\", err_msg)\n                                if isinstance(err_obj, dict) else str(err_obj)\n                            )\n                    except Exception:  # nosec B110\n                        pass\n                    raise RuntimeError(\n                        f\"Voyage API HTTP {http_err.code}: {err_msg}\"\n                    ) from http_err\n\n                response = _json.loads(raw)\n\n                if \"error\" in response:\n                    err = response[\"error\"]\n                    msg = err.get(\"message\", \"unknown\") if isinstance(err, dict) else str(err)\n                    raise RuntimeError(f\"Voyage API error: {msg}\")\n\n                data = response.get(\"data\", [])\n                if not data:\n                    raise RuntimeError(\"Voyage API returned empty data\")\n\n                any_has_index = any(\"index\" in item for item in data)\n                all_int_index = all(\n                    isinstance(item.get(\"index\"), int) for item in data\n                )","sourceCodeStart":715,"sourceCodeEnd":751,"githubUrl":"https://github.com/tirth8205/code-review-graph/blob/b58668751ab0c7670c078cf7cbd4d1f5b8e54f81/code_review_graph/embeddings.py#L715-L751","documentation":"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'.","triggerScenarios":"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.","commonSituations":"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.","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"],"exampleFix":null,"handlingStrategy":"retry","validationCode":"import os\nassert os.environ.get(\"VOYAGE_API_KEY\"), \"VOYAGE_API_KEY not set\"\nprovider.embed_query(\"ping\")  # smoke-test key+model before bulk run","typeGuard":null,"tryCatchPattern":"import time\nfor attempt in range(5):\n    try:\n        return provider.embed(texts)\n    except RuntimeError as e:\n        s = str(e)\n        if \"Voyage API HTTP 429\" in s or \"HTTP 5\" in s:\n            time.sleep(2 ** attempt); continue\n        raise  # 401/400 need credential/model fixes, not retries","preventionTips":["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"],"tags":["python","voyage","http-error","embeddings","api-error"],"backgroundTag":"http-error-response","analyzedSha":"b58668751ab0c7670c078cf7cbd4d1f5b8e54f81","analyzedAt":"2026-08-28T13:19:08.966Z","schemaVersion":2},"datasetVersion":"2026-08-28T16:17:29.566Z"}