tirth8205/code-review-graph · critical · RuntimeError

Voyage API returned {len(data)} embeddings for {len(texts)}

Error message

Voyage API returned {len(data)} embeddings for {len(texts)} inputs with no index field — refusing to misalign vectors.

What it means

No item in the response carries an 'index' field and the number of returned embeddings differs from the number of input texts. Without indices the provider cannot safely map vectors to texts, so it refuses rather than guess.

Source

Thrown at code_review_graph/embeddings.py:764

                    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
                )
                if all_int_index:
                    expected = set(range(len(texts)))
                    indices = [int(item["index"]) for item in data]
                    if len(set(indices)) != len(indices) or set(indices) != expected:
                        raise RuntimeError(
                            "Voyage API returned malformed indices "
                            f"(got {indices}, expected permutation of "
                            f"0..{len(texts) - 1}) — refusing to misalign vectors."
                        )
                    data = sorted(data, key=lambda item: int(item["index"]))
                elif not any_has_index:
                    if len(data) != len(texts):
                        raise RuntimeError(
                            f"Voyage API returned {len(data)} embeddings for "
                            f"{len(texts)} inputs with no index field — "
                            "refusing to misalign vectors."
                        )
                else:
                    raise RuntimeError(
                        "Voyage API returned mixed indexed/unindexed data — "
                        "refusing to misalign vectors."
                    )

                return [item["embedding"] for item in data]

            except Exception as e:
                is_retryable = False
                if isinstance(e, urllib.error.HTTPError):
                    is_retryable = e.code == 429 or 500 <= e.code < 600
                elif isinstance(e, (
                    urllib.error.URLError,

View on GitHub (pinned to b58668751a)

Solutions

  1. Retry with a smaller batch
  2. Compare the exact texts sent vs count returned; look for empty strings or duplicates being dropped
  3. Test against the real Voyage endpoint without CRG_VOYAGE_BASE_URL override
  4. Report the count mismatch with the request payload
Defensive patterns

Strategy: retry

Validate before calling

null

Try / catch

try:
    vecs = provider.embed(texts)
except RuntimeError as e:
    if "no index field" in str(e):
        vecs = provider.embed(texts)
    else:
        raise

Prevention

When it happens

Trigger: Calling embed() with N texts where the API returns M != N embeddings and omits index fields — typically dropped rows from a proxy or partial batch handling.

Common situations: Proxy/gateway filtering empty-string inputs differently than the client, upstream deduplication of identical texts, or batch-size mismatch bugs in custom base-url setups.

Related errors


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