Skip to content

fix(embedding): request float encoding_format on openai embedding calls - #938

Open
Vansh-Sharma27 wants to merge 2 commits into
plastic-labs:mainfrom
Vansh-Sharma27:fix/openai-embedding-encoding-format
Open

fix(embedding): request float encoding_format on openai embedding calls#938
Vansh-Sharma27 wants to merge 2 commits into
plastic-labs:mainfrom
Vansh-Sharma27:fix/openai-embedding-encoding-format

Conversation

@Vansh-Sharma27

@Vansh-Sharma27 Vansh-Sharma27 commented Jul 26, 2026

Copy link
Copy Markdown

Problem

Every embedding call fails when EMBEDDING_MODEL_CONFIG__TRANSPORT=openai points at an OpenAI-compatible provider that doesn't support base64 embeddings (e.g. OpenRouter hosting nvidia/nemotron-3-embed-1b:free):

ValueError: No embedding data received

Blast radius: create_conclusions, search_messages / semantic search, and the deriver's queued observations all fail.

Root cause

The openai SDK (v2.36.0, the version in uv.lock) defaults encoding_format to "base64" when the caller does not pass one:

# openai/resources/embeddings.py
if not is_given(encoding_format):
    params["encoding_format"] = "base64"

src/embedding_client.py passed nothing on either call path, so every request asked for base64. OpenRouter answers HTTP 200 with empty embedding data for models that don't support base64, and the SDK raises.

Fix

Pass encoding_format="float" explicitly on both openai call paths:

  • single-query path: _EmbeddingClient.embed()
  • batch path: _EmbeddingClient._process_batch()

These are the only two embeddings.create call sites in the codebase; the Gemini path is unaffected. Behavior against real OpenAI is unchanged apart from a slightly larger response payload: the SDK base64-decodes to the same float vectors today, so stored embeddings are identical. A side benefit of passing the format explicitly is that the SDK skips its base64-decode post-parser entirely.

Closes #932 — the issue's diagnosis was exact; this implements the fix it points to.

Testing

Check Result
New regression tests (both openai paths) fail with KeyError: 'encoding_format' before the fix, pass after
Full suite against pgvector/pgvector:pg15 1542 passed, 15 skipped, 3 failed (pre-existing, see below)
Same suite on a clean main checkout the same 3 failures (tests/crud/test_document.py dedup tests), in full runs and in isolation
ruff check / ruff format --check / basedpyright clean on the changed files
Live check against OpenRouter with nvidia/nemotron-3-embed-1b:free (the model from the issue) without encoding_format: ValueError: No embedding data received, reproducing the report exactly; with "float": real 2048-dim embeddings; the patched _EmbeddingClient pointed at OpenRouter embeds end-to-end

The 3 failing test_document tests reproduce identically on main and are unrelated to this change: the branch adds exactly 2 tests (1560 collected vs 1558 on main) and touches only the embedding client kwargs.

The existing exact-kwargs assertions in tests/llm/test_embedding_client.py were updated to include the new key, since the added parameter is intentional behavior.

Summary by CodeRabbit

  • Bug Fixes
    • Improved embedding request consistency by explicitly requesting floating-point vector results from OpenAI-compatible providers.
    • Ensured both single and batch embedding operations use the same response format.

… paths

The openai SDK defaults encoding_format to base64 when it is not passed. OpenAI-compatible providers that don't support base64 embeddings (e.g. OpenRouter with nvidia/nemotron-3-embed-1b:free) return HTTP 200 with empty data, and every embedding call fails with 'No embedding data received'.
The openai SDK defaults encoding_format to base64 when the caller does not pass one. OpenAI-compatible providers that don't support base64 embeddings (e.g. OpenRouter hosting nvidia/nemotron-3-embed-1b:free) answer HTTP 200 with empty embedding data, and every embedding call fails with 'No embedding data received', breaking conclusions, semantic search, and the deriver. Pass encoding_format='float' explicitly on both the single-query and batch call paths.
@coderabbitai

coderabbitai Bot commented Jul 26, 2026

Copy link
Copy Markdown
Contributor

Review Change Stack

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro Plus

Run ID: 96b2b89b-480e-4795-875d-bbe8bf56bb19

📥 Commits

Reviewing files that changed from the base of the PR and between 3ee890f and cd3b487.

📒 Files selected for processing (2)
  • src/embedding_client.py
  • tests/llm/test_embedding_client.py

Walkthrough

OpenAI-compatible embedding requests now explicitly request floating-point vectors in both single-query and batch paths. Tests update existing payload assertions and add coverage for the new request field.

Changes

Embedding request format

Layer / File(s) Summary
OpenAI request format
src/embedding_client.py
Single-query and batched OpenAI embedding requests now include encoding_format: "float".
Embedding format assertions
tests/llm/test_embedding_client.py
Existing payload expectations and new single-query and batch tests verify the explicit float encoding format, including dimension handling.

Estimated code review effort: 2 (Simple) | ~10 minutes

Suggested reviewers: vvoruganti

Poem

I’m a rabbit with vectors to spare,
Floating as softly as hops through the air.
Single or batch, the format is clear,
Float-bound embeddings now burrow near.
Tests twitch their noses: “Correct!” without fear.

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title clearly describes the main change: requesting float encoding for OpenAI embedding calls.
Linked Issues check ✅ Passed The fix matches #932 by setting float encoding on both the single and batch OpenAI embedding paths.
Out of Scope Changes check ✅ Passed The changes stay focused on the embedding client fix and regression tests, with no unrelated code paths introduced.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Embedding calls fail with OpenRouter: OpenAI SDK defaults to encoding_format=base64 which returns empty data

1 participant