BerriAI/litellm · error · ValueError

Embedding batch records do not have a chat-completion…

Error message

Embedding batch records do not have a chat-completion equivalent

What it means

Defensive invariant inside _transform_batch_body_to_chat_body: only TEXT_COMPLETION, RESPONSES and CHAT records can be normalized to a chat body. EMBEDDING records are routed to _map_openai_embedding_to_bedrock_params upstream (line ~896), so a user should never see this from the normal upload flow. Encountering it means the private helper was called directly with an EMBEDDING record, or a LiteLLM regression made classification inconsistent between the routing check and the transform.

Solutions

  1. Do not call the private static helper for embedding records — use _map_openai_embedding_to_bedrock_params (or the public create-file path)
  2. If you forked/subclassed the classifier, ensure one classification result is computed once per record and reused
  3. If this surfaces from a plain litellm.create_file call, capture the JSONL line and report a regression at github.com/BerriAI/litellm/issues
  4. Pin the LiteLLM version you validated against until fixed

Example fix

# before (custom code)
body = BedrockFilesConfig._transform_batch_body_to_chat_body(record["body"], BedrockBatchRecordKind.EMBEDDING)

# after
config = BedrockFilesConfig()
model_input = config._map_openai_embedding_to_bedrock_params(record["body"], model=record["body"].get("model", ""))
Defensive patterns

Strategy: try-catch

Try / catch

from litellm.types.llms.bedrock import BedrockBatchRecordKind

try:
    chat_body = BedrockFilesConfig._transform_batch_body_to_chat_body(body, kind)
except ValueError as e:
    if "chat-completion equivalent" in str(e):
        raise TypeError("embedding records must go through the embedding mapper") from e
    raise

Prevention

When it happens

Trigger: Custom code calling BedrockFilesConfig._transform_batch_body_to_chat_body(body, BedrockBatchRecordKind.EMBEDDING) directly; subclass or monkeypatch that changes _classify_batch_record between the routing branch and the transform call; a LiteLLM bug where the record kind is recomputed differently.

Common situations: Extending or testing BedrockFilesConfig internals; vendored/forked LiteLLM with modified classification; after upgrading LiteLLM versions that changed record-kind routing.

Related errors


AI-assisted analysis of BerriAI/litellm@77b7c6c40c (2026-08-18). Data as JSON: /api/errors/a751f78456fe6397. Report an issue: GitHub.

Appendix: source

Thrown at litellm/llms/bedrock/files/transformation.py:770

    @staticmethod
    def _transform_batch_body_to_chat_body(
        openai_request_body: _OpenAIBatchRecordBody,
        record_kind: BedrockBatchRecordKind,
    ) -> Mapping[str, object]:
        """
        Normalize a non-embedding batch body to the Chat Completions shape the
        per-provider Bedrock transformations expect.
        """
        match record_kind:
            case BedrockBatchRecordKind.TEXT_COMPLETION:
                return BedrockFilesConfig._transform_text_completion_body_to_chat_body(openai_request_body)
            case BedrockBatchRecordKind.RESPONSES:
                return BedrockFilesConfig._transform_responses_body_to_chat_body(openai_request_body)
            case BedrockBatchRecordKind.CHAT:
                return openai_request_body
            case BedrockBatchRecordKind.EMBEDDING:
                raise ValueError("Embedding batch records do not have a chat-completion equivalent")

    def _map_openai_to_bedrock_params(
        self,
        openai_request_body: Mapping[str, Any],
        model: str,
        provider: str | None = None,
    ) -> dict[str, object]:
        """
        Transform OpenAI request body to Bedrock-compatible modelInput
        parameters using existing transformation logic.

        Routes to the correct per-provider transformation so that the
        resulting dict matches the InvokeModel body that Bedrock expects
        for batch inference.
        """
        from litellm.types.utils import LlmProviders

        messages: Final = openai_request_body.get("messages", [])

View on GitHub (pinned to 77b7c6c40c)