{"record":{"id":"e31d6d0244ea4d09","repo":"tirth8205/code-review-graph","slug":"openai-api-returned-empty-data","errorCode":null,"errorMessage":"OpenAI API returned empty data","messagePattern":"OpenAI API returned empty data","errorType":"http","errorClass":"RuntimeError","httpStatus":null,"severity":"error","filePath":"code_review_graph/embeddings.py","lineNumber":520,"sourceCode":"                            )\n                    except Exception:  # nosec B110\n                        # Non-JSON error body is fine: we already seeded\n                        # err_msg with the raw body above, so fall through.\n                        pass\n                    raise RuntimeError(\n                        f\"OpenAI 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\"OpenAI API error: {msg}\")\n\n                data = response.get(\"data\", [])\n                if not data:\n                    raise RuntimeError(\"OpenAI API returned empty data\")\n                # OpenAI spec: data[i].index maps to input[i], but some\n                # compatible gateways re-order results or drop entries on\n                # partial failure, and others omit `index` entirely. Three\n                # disjoint cases:\n                #   1. All items have a valid int ``index``: must form a\n                #      permutation of 0..N-1, then sort and use.\n                #   2. NO item carries an ``index`` field: trust server\n                #      order, only verify count matches.\n                #   3. Anything in between (partial indices, str indices,\n                #      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]","sourceCodeStart":502,"sourceCodeEnd":538,"githubUrl":"https://github.com/tirth8205/code-review-graph/blob/b58668751ab0c7670c078cf7cbd4d1f5b8e54f81/code_review_graph/embeddings.py#L502-L538","documentation":"The OpenAI-compatible provider raises this RuntimeError when a successful response contains no `data` array (or an empty one). Per the OpenAI embeddings spec, data must contain one embedding per input, so an empty result means the gateway silently dropped the request — there is nothing to align, so the provider refuses rather than return wrong-length output.","triggerScenarios":"embed()/embed_query() where response.get(\"data\", []) is empty — e.g. an empty input list slipped through, or a compatible gateway returns 200 with no data on partial failure.","commonSituations":"Calling embed([]) accidentally (empty diff/chunk list), or flaky OpenAI-compatible gateways that omit data under load.","solutions":["Guard calls: skip the API when the input list is empty","If inputs were non-empty, retry the request — the gateway dropped data unexpectedly","Check the gateway/proxy version for known partial-failure bugs"],"exampleFix":"# before\nvectors = provider.embed(texts)\n# after\nvectors = provider.embed(texts) if texts else []","handlingStrategy":"validation","validationCode":"if not texts:\n    return []  # skip the API call entirely\nvecs = provider.embed(texts)","typeGuard":"def safe_embed(provider, texts):\n    if not texts:\n        return []\n    return provider.embed(texts)","tryCatchPattern":"try:\n    vecs = provider.embed(texts)\nexcept RuntimeError as e:\n    if \"empty data\" in str(e) and texts:\n        vecs = provider.embed(texts)  # one retry: gateway hiccup\n    else:\n        raise","preventionTips":["Never call embed() with an empty list — guard upstream","Filter empty strings out of chunks before embedding","Retry once on empty-data responses; persistent empties mean a broken gateway"],"tags":["python","openai","empty-response","embeddings","validation"],"backgroundTag":"empty-api-response","analyzedSha":"b58668751ab0c7670c078cf7cbd4d1f5b8e54f81","analyzedAt":"2026-08-28T13:19:08.966Z","schemaVersion":2},"datasetVersion":"2026-08-28T16:17:29.566Z"}