BerriAI/litellm · error · OCIError

{e.response.text}

Error message

{e.response.text}

What it means

Raised by OCIBaseTransformation.get_sync_custom_stream_wrapper when the synchronous streaming POST to the OCI Generative AI inference endpoint fails with an HTTP error status. The response body text from OCI is wrapped in an OCIError (a BaseLLMException subclass) carrying the upstream status code, so LiteLLM's standard exception mapping/logging can surface it.

Source

Thrown at litellm/llms/oci/chat/transformation.py:658

        messages: list,
        client: HTTPHandler | AsyncHTTPHandler | None = None,
        json_mode: bool | None = None,
        signed_json_body: bytes | None = None,
    ) -> "OCIStreamWrapper":
        if client is None or isinstance(client, AsyncHTTPHandler):
            client = _get_httpx_client(params={})

        try:
            response: Final = client.post(
                api_base,
                headers=headers,
                data=(signed_json_body if signed_json_body is not None else json.dumps(data)),
                stream=True,
                logging_obj=logging_obj,
                timeout=STREAMING_TIMEOUT,
            )
        except httpx.HTTPStatusError as e:
            raise OCIError(status_code=e.response.status_code, message=e.response.text)

        if response.status_code != 200:
            raise OCIError(status_code=response.status_code, message=response.text)

        return OCIStreamWrapper(
            completion_stream=_iter_sse_events(response.iter_text()),
            model=model,
            custom_llm_provider=custom_llm_provider,
            logging_obj=logging_obj,
        )

    @track_llm_api_timing()
    async def get_async_custom_stream_wrapper(
        self,
        model: str,
        custom_llm_provider: str,
        logging_obj: LiteLLMLoggingObj,
        api_base: str,

View on GitHub (pinned to 6c2dcb801b)

Solutions

  1. Inspect the OCIError.status_code and message: 401/403 means signing credentials are wrong, 404 means model OCID or region is wrong, 429 means back off and retry.
  2. Verify the model string uses a full OCID (ocid1.generativeai.model...) or an OCI-supported shorthand and that the region in the URL matches where the model is hosted.
  3. Confirm oci_user/oci_fingerprint/oci_tenancy/oci_key (or env vars OCI_USER etc.) belong to the same tenancy that has access to the model.
  4. For 429/5xx, retry with exponential backoff (litellm's built-in retry policy or your own).

Example fix

# before
resp = litellm.completion(model="oci/cohere.command-r-plus", messages=msgs, stream=True)

# after — catch the mapped provider error
import litellm
from litellm.llms.oci.common_utils import OCIError
try:
    resp = litellm.completion(model="oci/cohere.command-r-plus", messages=msgs, stream=True)
except OCIError as e:
    if e.status_code == 429:
        time.sleep(2 ** attempt)
    else:
        raise
Defensive patterns

Strategy: try-catch

Validate before calling

import os
required = ("OCI_USER", "OCI_FINGERPRINT", "OCI_TENANCY")
missing = [v for v in required if not os.environ.get(v)]
assert not missing and (os.environ.get("OCI_KEY") or os.environ.get("OCI_KEY_FILE")), f"missing: {missing}"

Type guard

from litellm.llms.oci.common_utils import OCIError

def is_oci_error(e: BaseException) -> bool:
    return isinstance(e, OCIError)

Try / catch

from litellm.llms.oci.common_utils import OCIError
try:
    stream = litellm.completion(model="oci/...", messages=m, stream=True)
except OCIError as e:
    if e.status_code in (429,) or (e.status_code or 0) >= 500:
        backoff_and_retry()
    else:
        raise  # 4xx = fix config/request, do not retry

Prevention

When it happens

Trigger: Calling litellm.completion(..., model='oci/...', stream=True) synchronously, where the signed POST to https://inference.generativeai.<region>.oci.oraclecloud.com returns a non-2xx or httpx raises HTTPStatusError: wrong model OCID, unauthorized signing (bad fingerprint/key), rate limiting (429), or a malformed request body rejected by the service.

Common situations: Typo'd model OCID; expired or mismatched RSA key fingerprint; region not entitled for the model; throttling under burst load; on-prem proxy returning 4xx. Note this except-branch is effectively dead code for plain client.post(stream=True) because httpx only raises HTTPStatusError after an explicit raise_for_status() call — non-200 statuses normally flow to the status_code check that raises the sibling error.

Related errors


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