BerriAI/litellm · error · OCIError

OCI embedText does not support token-array inputs. Convert t

Error message

OCI embedText does not support token-array inputs. Convert token lists to strings before calling embedding().

What it means

LiteLLM's OCI generative-ai embedding adapter normalizes the `input` argument into a flat list of strings before building the OCI embedText request. The OCI embedText API only accepts plain strings, not token arrays (lists of ints) like some OpenAI-compatible endpoints do. If any element of `input` is itself a list, this 400 error is raised during request transformation, before any HTTP call.

Source

Thrown at litellm/llms/oci/embed/transformation.py:200

        creds: Final = resolve_oci_credentials(optional_params)
        compartment_id: Final = creds["oci_compartment_id"]
        if not compartment_id:
            raise OCIError(
                status_code=400,
                message=(
                    "oci_compartment_id is required for OCI embedding requests. "
                    "Pass it as optional_params or set the OCI_COMPARTMENT_ID env var."
                ),
            )

        # Normalise input to a flat list of strings
        if isinstance(input, str):
            texts = [input]
        elif isinstance(input, list):
            texts = []
            for item in input:
                if isinstance(item, list):
                    raise OCIError(
                        status_code=400,
                        message=(
                            "OCI embedText does not support token-array inputs. "
                            "Convert token lists to strings before calling embedding()."
                        ),
                    )
                texts.append(item if isinstance(item, str) else str(item))
        else:
            texts = [str(input)]

        if len(texts) > OCI_EMBED_BATCH_LIMIT:
            raise OCIError(
                status_code=400,
                message=(
                    f"OCI embedText accepts at most {OCI_EMBED_BATCH_LIMIT} inputs per request "
                    f"(got {len(texts)}). Batch your requests."
                ),
            )

View on GitHub (pinned to 6c2dcb801b)

Solutions

  1. Convert token lists to strings before calling embedding(): decode with your tokenizer, e.g. `input=[tokenizer.decode(t) for t in token_lists]`.
  2. If you only have token arrays, embed them with a provider that supports them, or restructure your pipeline to keep raw text until the embedding call.
  3. Verify each item with `assert all(isinstance(x, str) for x in input)` before the call to fail fast on your side.

Example fix

# before
resp = litellm.embedding(model="oci/generative-ai-cohere-embed-v3", input=[[101, 102, 103]])

# after
resp = litellm.embedding(model="oci/generative-ai-cohere-embed-v3", input=["hello world"])
Defensive patterns

Strategy: validation

Validate before calling

def is_flat_str_list(input) -> bool:
    if isinstance(input, str):
        return True
    return isinstance(input, list) and all(isinstance(x, str) for x in input)

if not is_flat_str_list(input):
    input = [tokenizer.decode(t) if isinstance(t, list) else str(t) for t in input]

Type guard

def is_oci_embed_input_valid(input) -> bool:
    """True when input is a string or flat list of strings (no nested token arrays)."""
    if isinstance(input, str):
        return True
    return isinstance(input, list) and all(isinstance(i, str) for i in input)

Try / catch

try:
    resp = litellm.embedding(model="oci/...", input=input)
except litellm.llms.oci.OCIError as e:
    if "token-array" in str(e):
        input = [" ".join(map(str, t)) if isinstance(t, list) else t for t in input]
        resp = litellm.embedding(model="oci/...", input=input)
    else:
        raise

Prevention

When it happens

Trigger: Calling `litellm.embedding(model='oci/generative-ai-cohere-embed-v3', input=[[101, 102, 103], [104, 105]])` or passing tokenized text produced by a tokenizer (e.g. tiktoken output) as the input list. Any nested list inside the input list triggers it immediately in transform_embedding_request.

Common situations: Porting code from providers that accept token IDs (OpenAI legacy `embedding(input=[tokens])` usage), or piping tokenizer output directly into litellm.embedding. Also happens when a caller assumed litellm would transparently detokenize.

Related errors


AI-assisted analysis of BerriAI/litellm@6c2dcb801b (2026-08-15). Data as JSON: /api/errors/5c83682d9f4b80a8. Report an issue: GitHub.