langchain - ✅(Solved) Fix OpenRouter embeddings "No embedding data received" with OpenAIEmbeddings [2 pull requests, 1 comments, 2 participants]

Official PRs (…)
ON THIS PAGE

Recommended Tools

×6

Utilities matched from this issue’s tags and category — try them while you read without losing context.

GitHub issue graph ai analysis

Paste a GitHub issue URL. We fetch that issue, discover linked issues from bodies/comments/timeline, collect linked pull requests, and produce a structured English report.

The report is written in English Markdown for sharing and archival.

Helpful · Quick feedback

Loading…
GitHub stats
langchain-ai/langchain#35204Fetched 2026-04-08 00:27:16
View on GitHub
Comments
1
Participants
2
Timeline
15
Reactions
0
Timeline (top)
referenced ×6labeled ×3cross-referenced ×2closed ×1

I am trying to compute embeddings using OpenRouter API via using OpenAIEmbeddings as the main models.

I am aware that the issue might actually lie in how OpenRouter handles its embedding API, but I think the investigation has to start from LangChain side first so we tell more precisely where the mismatch between OpenAI and OpenRouter happens.

Alternative if you really need to solve this issue in your code (not using OpenAIEmbeddings):

# https://openrouter.ai/docs/api/reference/embeddings
import requests
response = requests.post(
  "https://openrouter.ai/api/v1/embeddings",
  headers={
    "Authorization": f"Bearer {os.environ["OPENROUTER_API_KEY"]}",
    "Content-Type": "application/json",
  },
  json={
    "model": "openai/text-embedding-3-small",
    "input": "The quick brown fox jumps over the lazy dog"
  }
)
data = response.json()
embedding = data["data"][0]["embedding"]
print(f"Embedding dimension: {len(embedding)}")
print(embedding[:5])
print("Approx size in ko with 64 bits floats", len(embedding)*4/1024)

Error Message

Traceback (most recent call last): File "/home/eric-burel/code/tmp/langchain-openai-openrouter-embeddings/embed.py", line 16, in <module> vector = embeddings.embed_query("Generate a short Python program that sends a message to an LLM") File "/home/eric-burel/code/tmp/langchain-openai-openrouter-embeddings/.venv/lib/python3.13/site-packages/langchain_openai/embeddings/base.py", line 759, in embed_query return self.embed_documents([text], **kwargs)[0] ~~~~~~~~~~~~~~~~~~~~^^^^^^^^^^^^^^^^^^ File "/home/eric-burel/code/tmp/langchain-openai-openrouter-embeddings/.venv/lib/python3.13/site-packages/langchain_openai/embeddings/base.py", line 709, in embed_documents return self._get_len_safe_embeddings( ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~^ texts, engine=engine, chunk_size=chunk_size, **kwargs ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ ) ^ File "/home/eric-burel/code/tmp/langchain-openai-openrouter-embeddings/.venv/lib/python3.13/site-packages/langchain_openai/embeddings/base.py", line 576, in _get_len_safe_embeddings response = self.client.create(input=batch_tokens, **client_kwargs) File "/home/eric-burel/code/tmp/langchain-openai-openrouter-embeddings/.venv/lib/python3.13/site-packages/openai/resources/embeddings.py", line 132, in create return self._post( ~~~~~~~~~~^ "/embeddings", ^^^^^^^^^^^^^^ ...<8 lines>... cast_to=CreateEmbeddingResponse, ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ ) ^ File "/home/eric-burel/code/tmp/langchain-openai-openrouter-embeddings/.venv/lib/python3.13/site-packages/openai/_base_client.py", line 1297, in post return cast(ResponseT, self.request(cast_to, opts, stream=stream, stream_cls=stream_cls)) ~~~~~~~~~~~~^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ File "/home/eric-burel/code/tmp/langchain-openai-openrouter-embeddings/.venv/lib/python3.13/site-packages/openai/_base_client.py", line 1075, in request return self._process_response( ~~~~~~~~~~~~~~~~~~~~~~^ cast_to=cast_to, ^^^^^^^^^^^^^^^^ ...<4 lines>... retries_taken=retries_taken, ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ ) ^ File "/home/eric-burel/code/tmp/langchain-openai-openrouter-embeddings/.venv/lib/python3.13/site-packages/openai/_base_client.py", line 1164, in _process_response return api_response.parse() ~~~~~~~~~~~~~~~~~~^^ File "/home/eric-burel/code/tmp/langchain-openai-openrouter-embeddings/.venv/lib/python3.13/site-packages/openai/_response.py", line 325, in parse parsed = self._options.post_parser(parsed) File "/home/eric-burel/code/tmp/langchain-openai-openrouter-embeddings/.venv/lib/python3.13/site-packages/openai/resources/embeddings.py", line 116, in parser raise ValueError("No embedding data received") ValueError: No embedding data received

Root Cause

I am trying to compute embeddings using OpenRouter API via using OpenAIEmbeddings as the main models.

I am aware that the issue might actually lie in how OpenRouter handles its embedding API, but I think the investigation has to start from LangChain side first so we tell more precisely where the mismatch between OpenAI and OpenRouter happens.

Alternative if you really need to solve this issue in your code (not using OpenAIEmbeddings):

# https://openrouter.ai/docs/api/reference/embeddings
import requests
response = requests.post(
  "https://openrouter.ai/api/v1/embeddings",
  headers={
    "Authorization": f"Bearer {os.environ["OPENROUTER_API_KEY"]}",
    "Content-Type": "application/json",
  },
  json={
    "model": "openai/text-embedding-3-small",
    "input": "The quick brown fox jumps over the lazy dog"
  }
)
data = response.json()
embedding = data["data"][0]["embedding"]
print(f"Embedding dimension: {len(embedding)}")
print(embedding[:5])
print("Approx size in ko with 64 bits floats", len(embedding)*4/1024)

Fix Action

Fix / Workaround

  • This is a bug, not a usage question.
  • I added a clear and descriptive title that summarizes this issue.
  • I used the GitHub search to find a similar question and didn't find it.
  • I am sure that this is a bug in LangChain rather than my code.
  • The bug is not resolved by updating to the latest stable version of LangChain (or the specific integration package).
  • This is not related to the langchain-community package.
  • I posted a self-contained, minimal, reproducible example. A maintainer can copy it and run it AS IS.

Other Dependencies

httpx: 0.28.1 jsonpatch: 1.33 openai: 2.20.0 orjson: 3.11.7 packaging: 26.0 pydantic: 2.12.5 pyyaml: 6.0.3 requests: 2.32.5 requests-toolbelt: 1.0.0 tenacity: 9.1.4 tiktoken: 0.12.0 typing-extensions: 4.15.0 uuid-utils: 0.14.0 xxhash: 3.6.0 zstandard: 0.25.0

PR fix notes

PR #35251: fix(openai): enhance error message for non-OpenAI embedding providers

Description (problem / solution / changelog)

Summary

Fixes #35204 (umbrella: #34328)

When using OpenAIEmbeddings with a non-OpenAI base_url (e.g. OpenRouter, Ollama, vLLM), the call fails with an unhelpful ValueError: No embedding data received. Root causes:

  1. Token arrays as input - the default path tokenizes text via tiktoken and sends list[int], which non-OpenAI providers do not support.
  2. Base64 encoding - the openai SDK auto-sets encoding_format="base64", which non-OpenAI providers do not support.

This PR:

  • Enhanced error message: Wraps the 4 client.create() call sites (sync/async, tokenized/plain) to detect "No embedding data received" when base_url is non-OpenAI, and re-raises with actionable guidance:

    check_embedding_ctx_length=False to send raw text instead of tokens, and/or model_kwargs={"encoding_format": "float"} to avoid base64 encoding.

  • Updated docstrings: Adds an "OpenAI-compatible APIs" section to the class docstring with a working example, and clarifies check_embedding_ctx_length and tiktoken_enabled for non-OpenAI providers.
  • Unit tests: 10 new tests covering all 4 call paths, passthrough for OpenAI URLs, passthrough for unrelated errors, and _is_openai_url property.

Test plan

  • All 17 unit tests pass (pytest libs/partners/openai/tests/unit_tests/embeddings/test_base.py)
  • Existing tests unaffected (no changes to OpenAI-native code paths)
  • Verify enhanced error triggers with actual OpenRouter endpoint (manual)

Changed files

  • libs/partners/openai/langchain_openai/embeddings/base.py (modified, +81/-12)
  • libs/partners/openai/tests/unit_tests/embeddings/test_base.py (modified, +114/-1)

PR #35252: fix(openai): enhance reference for non-OpenAI embedding providers

Description (problem / solution / changelog)

Summary

Fixes #35204 (umbrella: #34328)

When using OpenAIEmbeddings with a non-OpenAI base_url (e.g. OpenRouter, Ollama, vLLM), the call fails with an unhelpful ValueError: No embedding data received. Root causes:

  1. Token arrays as input - the default path tokenizes text via tiktoken and sends list[int], which non-OpenAI providers do not support.
  2. Base64 encoding - the openai SDK auto-sets encoding_format="base64", which non-OpenAI providers do not support.

This PR:

  • Enhanced error message: Wraps the 4 client.create() call sites (sync/async, tokenized/plain) to detect "No embedding data received" when base_url is non-OpenAI, and re-raises with actionable guidance:

    check_embedding_ctx_length=False to send raw text instead of tokens, and/or model_kwargs={"encoding_format": "float"} to avoid base64 encoding.

  • Updated docstrings: Adds an "OpenAI-compatible APIs" section to the class docstring with a working example, and clarifies check_embedding_ctx_length and tiktoken_enabled for non-OpenAI providers.
  • Unit tests: 10 new tests covering all 4 call paths, passthrough for OpenAI URLs, passthrough for unrelated errors, and _is_openai_url property.

Test plan

  • All 17 unit tests pass (pytest libs/partners/openai/tests/unit_tests/embeddings/test_base.py)
  • Existing tests unaffected (no changes to OpenAI-native code paths)
  • Verify enhanced error triggers with actual OpenRouter endpoint (manual)

Changed files

  • libs/partners/openai/langchain_openai/embeddings/base.py (modified, +27/-3)

Code Example

# pip install langchain-openai

from langchain_openai import OpenAIEmbeddings
import os

# Working (for reference)
embeddings_oai = OpenAIEmbeddings(
     api_key=os.environ["OPENAI_API_KEY"]
     )
vector_oai = embeddings_oai.embed_query("Generate a short Python program that sends a message to an LLM")
print(vector_oai[:5])

# Not working
embeddings = OpenAIEmbeddings(
     model="sentence-transformers/paraphrase-minilm-l6-v2",
    # Using openrouter
     base_url="https://openrouter.ai/api/v1",
     api_key=os.environ["OPENROUTER_API_KEY"],
     )
vector = embeddings.embed_query("Generate a short Python program that sends a message to an LLM")
print(vector[:5])

---

Traceback (most recent call last):
  File "/home/eric-burel/code/tmp/langchain-openai-openrouter-embeddings/embed.py", line 16, in <module>
    vector = embeddings.embed_query("Generate a short Python program that sends a message to an LLM")
  File "/home/eric-burel/code/tmp/langchain-openai-openrouter-embeddings/.venv/lib/python3.13/site-packages/langchain_openai/embeddings/base.py", line 759, in embed_query
    return self.embed_documents([text], **kwargs)[0]
           ~~~~~~~~~~~~~~~~~~~~^^^^^^^^^^^^^^^^^^
  File "/home/eric-burel/code/tmp/langchain-openai-openrouter-embeddings/.venv/lib/python3.13/site-packages/langchain_openai/embeddings/base.py", line 709, in embed_documents
    return self._get_len_safe_embeddings(
           ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~^
        texts, engine=engine, chunk_size=chunk_size, **kwargs
        ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
    )
    ^
  File "/home/eric-burel/code/tmp/langchain-openai-openrouter-embeddings/.venv/lib/python3.13/site-packages/langchain_openai/embeddings/base.py", line 576, in _get_len_safe_embeddings
    response = self.client.create(input=batch_tokens, **client_kwargs)
  File "/home/eric-burel/code/tmp/langchain-openai-openrouter-embeddings/.venv/lib/python3.13/site-packages/openai/resources/embeddings.py", line 132, in create
    return self._post(
           ~~~~~~~~~~^
        "/embeddings",
        ^^^^^^^^^^^^^^
    ...<8 lines>...
        cast_to=CreateEmbeddingResponse,
        ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
    )
    ^
  File "/home/eric-burel/code/tmp/langchain-openai-openrouter-embeddings/.venv/lib/python3.13/site-packages/openai/_base_client.py", line 1297, in post
    return cast(ResponseT, self.request(cast_to, opts, stream=stream, stream_cls=stream_cls))
                           ~~~~~~~~~~~~^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/home/eric-burel/code/tmp/langchain-openai-openrouter-embeddings/.venv/lib/python3.13/site-packages/openai/_base_client.py", line 1075, in request
    return self._process_response(
           ~~~~~~~~~~~~~~~~~~~~~~^
        cast_to=cast_to,
        ^^^^^^^^^^^^^^^^
    ...<4 lines>...
        retries_taken=retries_taken,
        ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
    )
    ^
  File "/home/eric-burel/code/tmp/langchain-openai-openrouter-embeddings/.venv/lib/python3.13/site-packages/openai/_base_client.py", line 1164, in _process_response
    return api_response.parse()
           ~~~~~~~~~~~~~~~~~~^^
  File "/home/eric-burel/code/tmp/langchain-openai-openrouter-embeddings/.venv/lib/python3.13/site-packages/openai/_response.py", line 325, in parse
    parsed = self._options.post_parser(parsed)
  File "/home/eric-burel/code/tmp/langchain-openai-openrouter-embeddings/.venv/lib/python3.13/site-packages/openai/resources/embeddings.py", line 116, in parser
    raise ValueError("No embedding data received")
ValueError: No embedding data received

---

# https://openrouter.ai/docs/api/reference/embeddings
import requests
response = requests.post(
  "https://openrouter.ai/api/v1/embeddings",
  headers={
    "Authorization": f"Bearer {os.environ["OPENROUTER_API_KEY"]}",
    "Content-Type": "application/json",
  },
  json={
    "model": "openai/text-embedding-3-small",
    "input": "The quick brown fox jumps over the lazy dog"
  }
)
data = response.json()
embedding = data["data"][0]["embedding"]
print(f"Embedding dimension: {len(embedding)}")
print(embedding[:5])
print("Approx size in ko with 64 bits floats", len(embedding)*4/1024)
RAW_BUFFERClick to expand / collapse

Checked other resources

  • This is a bug, not a usage question.
  • I added a clear and descriptive title that summarizes this issue.
  • I used the GitHub search to find a similar question and didn't find it.
  • I am sure that this is a bug in LangChain rather than my code.
  • The bug is not resolved by updating to the latest stable version of LangChain (or the specific integration package).
  • This is not related to the langchain-community package.
  • I posted a self-contained, minimal, reproducible example. A maintainer can copy it and run it AS IS.

Package (Required)

  • langchain
  • langchain-openai
  • langchain-anthropic
  • langchain-classic
  • langchain-core
  • langchain-model-profiles
  • langchain-tests
  • langchain-text-splitters
  • langchain-chroma
  • langchain-deepseek
  • langchain-exa
  • langchain-fireworks
  • langchain-groq
  • langchain-huggingface
  • langchain-mistralai
  • langchain-nomic
  • langchain-ollama
  • langchain-perplexity
  • langchain-qdrant
  • langchain-xai
  • Other / not sure / general

Related Issues / PRs

Umbrella issue #34328 is tracking all the small issues we may face when using OpenAI as a de-facto standard to connect to alternative providers such as OpenRouter

Reproduction Steps / Example Code (Python)

# pip install langchain-openai

from langchain_openai import OpenAIEmbeddings
import os

# Working (for reference)
embeddings_oai = OpenAIEmbeddings(
     api_key=os.environ["OPENAI_API_KEY"]
     )
vector_oai = embeddings_oai.embed_query("Generate a short Python program that sends a message to an LLM")
print(vector_oai[:5])

# Not working
embeddings = OpenAIEmbeddings(
     model="sentence-transformers/paraphrase-minilm-l6-v2",
    # Using openrouter
     base_url="https://openrouter.ai/api/v1",
     api_key=os.environ["OPENROUTER_API_KEY"],
     )
vector = embeddings.embed_query("Generate a short Python program that sends a message to an LLM")
print(vector[:5])

Error Message and Stack Trace (if applicable)

Until line --> 576 response = self.client.create(input=batch_tokens, **client_kwargs), the data are correct, so I guess the API call to OpenRouter doesn't get the expected data structure as a response.

Traceback (most recent call last):
  File "/home/eric-burel/code/tmp/langchain-openai-openrouter-embeddings/embed.py", line 16, in <module>
    vector = embeddings.embed_query("Generate a short Python program that sends a message to an LLM")
  File "/home/eric-burel/code/tmp/langchain-openai-openrouter-embeddings/.venv/lib/python3.13/site-packages/langchain_openai/embeddings/base.py", line 759, in embed_query
    return self.embed_documents([text], **kwargs)[0]
           ~~~~~~~~~~~~~~~~~~~~^^^^^^^^^^^^^^^^^^
  File "/home/eric-burel/code/tmp/langchain-openai-openrouter-embeddings/.venv/lib/python3.13/site-packages/langchain_openai/embeddings/base.py", line 709, in embed_documents
    return self._get_len_safe_embeddings(
           ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~^
        texts, engine=engine, chunk_size=chunk_size, **kwargs
        ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
    )
    ^
  File "/home/eric-burel/code/tmp/langchain-openai-openrouter-embeddings/.venv/lib/python3.13/site-packages/langchain_openai/embeddings/base.py", line 576, in _get_len_safe_embeddings
    response = self.client.create(input=batch_tokens, **client_kwargs)
  File "/home/eric-burel/code/tmp/langchain-openai-openrouter-embeddings/.venv/lib/python3.13/site-packages/openai/resources/embeddings.py", line 132, in create
    return self._post(
           ~~~~~~~~~~^
        "/embeddings",
        ^^^^^^^^^^^^^^
    ...<8 lines>...
        cast_to=CreateEmbeddingResponse,
        ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
    )
    ^
  File "/home/eric-burel/code/tmp/langchain-openai-openrouter-embeddings/.venv/lib/python3.13/site-packages/openai/_base_client.py", line 1297, in post
    return cast(ResponseT, self.request(cast_to, opts, stream=stream, stream_cls=stream_cls))
                           ~~~~~~~~~~~~^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/home/eric-burel/code/tmp/langchain-openai-openrouter-embeddings/.venv/lib/python3.13/site-packages/openai/_base_client.py", line 1075, in request
    return self._process_response(
           ~~~~~~~~~~~~~~~~~~~~~~^
        cast_to=cast_to,
        ^^^^^^^^^^^^^^^^
    ...<4 lines>...
        retries_taken=retries_taken,
        ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
    )
    ^
  File "/home/eric-burel/code/tmp/langchain-openai-openrouter-embeddings/.venv/lib/python3.13/site-packages/openai/_base_client.py", line 1164, in _process_response
    return api_response.parse()
           ~~~~~~~~~~~~~~~~~~^^
  File "/home/eric-burel/code/tmp/langchain-openai-openrouter-embeddings/.venv/lib/python3.13/site-packages/openai/_response.py", line 325, in parse
    parsed = self._options.post_parser(parsed)
  File "/home/eric-burel/code/tmp/langchain-openai-openrouter-embeddings/.venv/lib/python3.13/site-packages/openai/resources/embeddings.py", line 116, in parser
    raise ValueError("No embedding data received")
ValueError: No embedding data received

Description

I am trying to compute embeddings using OpenRouter API via using OpenAIEmbeddings as the main models.

I am aware that the issue might actually lie in how OpenRouter handles its embedding API, but I think the investigation has to start from LangChain side first so we tell more precisely where the mismatch between OpenAI and OpenRouter happens.

Alternative if you really need to solve this issue in your code (not using OpenAIEmbeddings):

# https://openrouter.ai/docs/api/reference/embeddings
import requests
response = requests.post(
  "https://openrouter.ai/api/v1/embeddings",
  headers={
    "Authorization": f"Bearer {os.environ["OPENROUTER_API_KEY"]}",
    "Content-Type": "application/json",
  },
  json={
    "model": "openai/text-embedding-3-small",
    "input": "The quick brown fox jumps over the lazy dog"
  }
)
data = response.json()
embedding = data["data"][0]["embedding"]
print(f"Embedding dimension: {len(embedding)}")
print(embedding[:5])
print("Approx size in ko with 64 bits floats", len(embedding)*4/1024)

System Info

System Information

OS: Linux OS Version: #14-Ubuntu SMP PREEMPT_DYNAMIC Fri Jan 9 17:01:16 UTC 2026 Python Version: 3.13.9 (main, Oct 28 2025, 12:10:42) [Clang 20.1.4 ]

Package Information

langchain_core: 1.2.12 langsmith: 0.7.1 langchain_openai: 1.1.9

Optional packages not installed

langserve

Other Dependencies

httpx: 0.28.1 jsonpatch: 1.33 openai: 2.20.0 orjson: 3.11.7 packaging: 26.0 pydantic: 2.12.5 pyyaml: 6.0.3 requests: 2.32.5 requests-toolbelt: 1.0.0 tenacity: 9.1.4 tiktoken: 0.12.0 typing-extensions: 4.15.0 uuid-utils: 0.14.0 xxhash: 3.6.0 zstandard: 0.25.0

extent analysis

Problem Summary

The issue is that the OpenAIEmbeddings class from the langchain_openai package fails to compute embeddings using the OpenRouter API, resulting in a ValueError: No embedding data received error.

Root Cause Analysis

The root cause is likely due to the mismatch between the expected response format from OpenRouter and the actual response received by LangChain.

Fix Plan

To fix this issue, we need to modify the OpenAIEmbeddings class to handle the response format from OpenRouter correctly.

Step 1: Update the OpenAIEmbeddings class to handle the response format from OpenRouter

We need to update the embed_documents method in the OpenAIEmbeddings class to handle the response format from OpenRouter. Specifically, we need to parse the response JSON and extract the embedding data.

Step 2: Modify the embed_documents method to handle the response format from OpenRouter

def embed_documents(self, texts, engine=None, chunk_size=None, **kwargs):
    # ...
    response = self.client.create(input=batch_tokens, **client_kwargs)
    # ...
    data = response.json()
    embedding_data = data["data"][0]["embedding"]
    # ...

Step 3: Update the embed_query method to use the updated embed_documents method

def embed_query(self, text, **kwargs):
    return self.embed_documents([text], **kwargs)[0]

Step 4: Test the updated OpenAIEmbeddings class

We need to test the updated OpenAIEmbeddings class to ensure that it can handle the response format from OpenRouter correctly.

Verification

To verify that the fix worked, we can run the following test:

embeddings = OpenAIEmbeddings(
    model="sentence-transformers/paraphrase-minilm-l6-v2",

Vote matrix · Quick signals

Works
Did the solution work? Tap to confirm.
Easy Fix
Was it a quick fix?
Time Saver
Did it save you time?
Blocking
Was it severely blocking?
Common Issue
Are others likely hitting this too?
Flaky / Intermittent
Is it intermittent?
Verified / Reproducible
Can you reproduce it reliably?
Loading…

Still need to ship something?

×6

Another batch ranked right after the header list — different links, same matching logic.

Back to top recommendations

TRENDING