{"record":{"id":"f082139b040ec9b7","repo":"tirth8205/code-review-graph","slug":"openai-api-returned-len-data-embeddings-for-le","errorCode":null,"errorMessage":"OpenAI API returned {len(data)} embeddings for {len(texts)} inputs with no index field — refusing to misalign vectors.","messagePattern":"OpenAI API returned (.+?) embeddings for (.+?) inputs with no index field — refusing to misalign vectors\\.","errorType":"http","errorClass":"RuntimeError","httpStatus":null,"severity":"error","filePath":"code_review_graph/embeddings.py","lineNumber":548,"sourceCode":"                #      missing on some): refuse. Zipping server order in\n                #      that case would happily misalign the indexed items.\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                )\n                if all_int_index:\n                    expected = set(range(len(texts)))\n                    indices = [int(item[\"index\"]) for item in data]\n                    if len(set(indices)) != len(indices) or set(indices) != expected:\n                        raise RuntimeError(\n                            \"OpenAI API returned malformed indices \"\n                            f\"(got {indices}, expected permutation of \"\n                            f\"0..{len(texts) - 1}) — refusing to misalign vectors.\"\n                        )\n                    data = sorted(data, key=lambda item: int(item[\"index\"]))\n                elif not any_has_index:\n                    if len(data) != len(texts):\n                        raise RuntimeError(\n                            f\"OpenAI API returned {len(data)} embeddings for \"\n                            f\"{len(texts)} inputs with no index field — \"\n                            \"refusing to misalign vectors.\"\n                        )\n                else:\n                    # Mixed: some items have index, others don't (or carry\n                    # non-int index). Server order would silently misplace\n                    # the indexed items, so we refuse.\n                    raise RuntimeError(\n                        \"OpenAI API returned mixed indexed/unindexed data — \"\n                        \"refusing to misalign vectors.\"\n                    )\n\n                vectors = [item[\"embedding\"] for item in data]\n                if vectors and self._dimension is None:\n                    self._dimension = len(vectors[0])\n                return vectors\n","sourceCodeStart":530,"sourceCodeEnd":566,"githubUrl":"https://github.com/tirth8205/code-review-graph/blob/b58668751ab0c7670c078cf7cbd4d1f5b8e54f81/code_review_graph/embeddings.py#L530-L566","documentation":"When NONE of the returned embedding items carry an `index` field, the only safe assumption is positional correspondence, which requires len(data) == len(texts). If the counts differ, the provider raises this RuntimeError rather than guess how to zip server order onto the inputs, since a mismatch would silently assign vectors to the wrong texts.","triggerScenarios":"embed() against a gateway that omits `index` in embeddings responses and returns fewer or more embeddings than input texts (e.g. dropped empty-string inputs or concatenated batches).","commonSituations":"Gateways that filter out empty or oversized inputs server-side, or that merge/split batches — producing count mismatches with no index metadata to recover the mapping.","solutions":["Pre-validate inputs: remove empty/oversized strings before calling embed","Compare len(data) vs len(texts) from the message to confirm a server-side drop, then reduce batch size and retry","Upgrade or fix the gateway to either return index fields or exact-count positional data"],"exampleFix":"# before\ntexts = [t for t in chunks]\nvectors = provider.embed(texts)\n# after\ntexts = [t for t in chunks if t.strip()]\nvectors = provider.embed(texts)","handlingStrategy":"validation","validationCode":"# Normalize inputs: gateways drop empty/oversized items, causing count mismatch\ntexts = [t.strip() for t in texts if t and t.strip()]\nassert texts, \"no non-empty texts to embed\"","typeGuard":null,"tryCatchPattern":"try:\n    vecs = provider.embed(batch)\nexcept RuntimeError as e:\n    if \"no index field\" in str(e):\n        vecs = provider.embed(batch)  # retry once; persistent mismatch = gateway bug\n    else:\n        raise","preventionTips":["Strip empty/whitespace-only strings before embedding","Keep batch sizes modest so server-side drops are rare","After any embed call, assert len(vectors) == len(inputs) as a cheap invariant"],"tags":["python","openai","embeddings","count-mismatch","misalignment-guard"],"backgroundTag":"response-length-mismatch","analyzedSha":"b58668751ab0c7670c078cf7cbd4d1f5b8e54f81","analyzedAt":"2026-08-28T13:19:08.966Z","schemaVersion":2},"datasetVersion":"2026-08-28T16:17:29.566Z"}