BerriAI/litellm · error · ValueError
Missing expected key in embedding response: {e}
Error message
Missing expected key in embedding response: {e} What it means
ValueError raised while LiteLLM converts an embedding response into the cacheable per-item dict form: a KeyError occurred while accessing expected attributes/keys of the response data. The f-string interpolates the missing key name (the KeyError), telling you exactly which field was absent. It signals a provider response shape that does not match what the caching layer expects for embeddings.
Source
Thrown at litellm/caching/caching.py:726
"embedding": data.get("embedding"),
"index": data.get("index"),
"object": data.get("object"),
"model": model,
"prompt_tokens": prompt_tokens,
"prompt_tokens_details": prompt_tokens_details,
}
else:
data = vars(embedding_response)
return {
"embedding": data.get("embedding"),
"index": data.get("index"),
"object": data.get("object"),
"model": model,
"prompt_tokens": prompt_tokens,
"prompt_tokens_details": prompt_tokens_details,
}
except KeyError as e:
raise ValueError(f"Missing expected key in embedding response: {e}")
def _get_per_item_prompt_tokens_details(
self,
result: EmbeddingResponse,
idx_in_result_data: int,
) -> dict | None:
"""
Extract per-item prompt_tokens_details from a response for caching.
For single-item responses (common for multimodal providers like Bedrock Titan,
Nova, Vertex AI), returns the full prompt_tokens_details.
For multi-item responses, distributes integer fields evenly across items
so that summing all per-item details reconstructs the original totals.
"""
if result.usage is None or result.usage.prompt_tokens_details is None:
return None
details: Final = result.usage.prompt_tokens_detailsView on GitHub (pinned to 6c2dcb801b)
Solutions
- Check the interpolated key name in the message to see which field is missing from the embedding response data.
- Upgrade LiteLLM — provider transformation/cache extraction mismatches are usually fixed in patch releases.
- As a workaround, disable caching for that embedding model (or route around the cache) until compatible.
- File an upstream issue with the provider name and response sample.
Example fix
# before
litellm.cache = litellm.Cache(type="redis")
litellm.embedding(model="provider/embed-model", input=["hi"]) # -> ValueError: Missing expected key
# after (temporarily bypass cache for that model)
litellm.embedding(model="provider/embed-model", input=["hi"], cache={"no-cache": True}) Defensive patterns
Strategy: fallback
Validate before calling
def embedding_response_is_well_formed(resp) -> bool:
try:
return all(d.get("embedding") is not None and d.get("index") is not None for d in resp.data)
except (AttributeError, KeyError):
return False Type guard
def is_cacheable_embedding_response(resp) -> bool:
return hasattr(resp, "data") and all(isinstance(d, dict) or hasattr(d, "embedding") for d in getattr(resp, "data", [])) Try / catch
try:
resp = litellm.embedding(model=embed_model, input=inp) # cache enabled
except ValueError as e:
if "Missing expected key in embedding response" in str(e):
with cache_disabled():
resp = litellm.embedding(model=embed_model, input=inp)
else:
raise Prevention
- Keep LiteLLM updated when adding new embedding providers.
- Smoke-test each embedding provider with caching enabled in staging before rollout.
- Maintain a per-model cache toggle so one bad provider doesn't break all embedding traffic.
When it happens
Trigger: Using response caching with embeddings where the provider's EmbeddingResponse data items lack standard keys (e.g. no 'embedding' or 'index'), so the dict/vars-based extraction in the caching helper raises KeyError, which is caught and re-raised as this ValueError.
Common situations: A new or non-standard embedding provider whose transformation returns incomplete data objects; a LiteLLM version where a provider transformation was updated but the caching extraction was not; multimodal providers with atypical per-item structure.
Related errors
- Setting user/encoding format is not supported by {custom_llm
- input must be a string or a list
- LLM client cache lazy import: unknown attribute {name!r}
- WXO: No run_id in response: {run_data}
- cache key is None
AI-assisted analysis of BerriAI/litellm@6c2dcb801b (2026-08-15).
Data as JSON: /api/errors/1eb5153f7e148967.
Report an issue: GitHub.