BerriAI/litellm · critical · OCIError

oci_compartment_id is required for OCI embedding requests. P

Error message

oci_compartment_id is required for OCI embedding requests. Pass it as optional_params or set the OCI_COMPARTMENT_ID env var.

What it means

OCIEmbeddingConfig.transform_embedding_request re-checks that oci_compartment_id resolved from optional_params or OCI_COMPARTMENT_ID is non-empty and raises OCIError(400) if not. OCI's embedding endpoint requires onboarding/serving requests to name a compartment, so the request cannot even be built without it.

Source

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

            request_data=request_data,
            api_base=api_base,
            api_key=api_key,
            model=model,
            stream=stream,
            fake_stream=fake_stream,
        )

    def transform_embedding_request(
        self,
        model: str,
        input: AllEmbeddingInputValues,
        optional_params: dict,
        headers: dict,
    ) -> dict:
        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. "

View on GitHub (pinned to 6c2dcb801b)

Solutions

  1. Set OCI_COMPARTMENT_ID to the compartment OCID where the embedding model is onboarded.
  2. Or pass it per call: litellm.embedding(..., extra_body={'oci_compartment_id': ocid}).
  3. Grab the OCID from OCI Console > Identity > Compartments (starts with ocid1.compartment.oc1.).
  4. Validate presence at app startup rather than at request time.

Example fix

# before
litellm.embedding(model="oci/generic.embedding.multilingual.v1.5", input=texts)
# OCIError 400: oci_compartment_id required

# after
os.environ["OCI_COMPARTMENT_ID"] = "ocid1.compartment.oc1..aaaa..."
litellm.embedding(model="oci/generic.embedding.multilingual.v1.5", input=texts)
Defensive patterns

Strategy: validation

Validate before calling

import os
compartment = os.environ.get("OCI_COMPARTMENT_ID", "")
assert compartment.startswith("ocid1.compartment."), \
    f"OCI_COMPARTMENT_ID must be a compartment OCID, got {compartment!r}"

Type guard

def is_compartment_ocid(v: object) -> bool:
    return isinstance(v, str) and v.startswith("ocid1.compartment.")

Try / catch

from litellm.llms.oci.common_utils import OCIError
try:
    litellm.embedding(model="oci/generic.embedding...", input=texts)
except OCIError as e:
    if e.status_code == 400 and "oci_compartment_id is required" in str(e):
        os.environ["OCI_COMPARTMENT_ID"] = fetch_compartment_for_tenant()
    raise

Prevention

When it happens

Trigger: litellm.embedding with custom_llm_provider='oci' where OCI_COMPARTMENT_ID is unset/empty and no oci_compartment_id was passed; env var set in the shell but not in the deployed process; compartment id set only for the chat path.

Common situations: Reusing chat-credential setup for embeddings and forgetting the compartment; multi-tenant apps where the compartment should be selected per request; empty-string defaults from Helm/env templating.

Related errors


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