BerriAI/litellm · error · NLPCloudError

{json.dumps(completion_response)}

Error message

{json.dumps(completion_response)}

What it means

Raised by litellm's NLPCloud chat transformer when extracting the response fields fails — typically completion_response has no "generated_text" key (so the indexing raises), meaning NLP Cloud returned valid JSON that is neither a normal completion nor an error object. The whole JSON body is serialized into the message for debugging.

Source

Thrown at litellm/llms/nlp_cloud/chat/transformation.py:203

            additional_args={"complete_input_dict": request_data},
        )

        ## RESPONSE OBJECT
        try:
            completion_response: Final = raw_response.json()
        except Exception:
            raise NLPCloudError(message=raw_response.text, status_code=raw_response.status_code)
        if "error" in completion_response:
            raise NLPCloudError(
                message=completion_response["error"],
                status_code=raw_response.status_code,
            )
        else:
            try:
                if len(completion_response["generated_text"]) > 0:
                    model_response.choices[0].message.content = completion_response["generated_text"]
            except Exception:
                raise NLPCloudError(
                    message=json.dumps(completion_response),
                    status_code=raw_response.status_code,
                )

        ## CALCULATING USAGE - baseten charges on time, not tokens - have some mapping of cost here.
        prompt_tokens: Final = completion_response["nb_input_tokens"]
        completion_tokens: Final = completion_response["nb_generated_tokens"]

        model_response.created = int(time.time())
        model_response.model = model
        usage: Final = Usage(
            prompt_tokens=prompt_tokens,
            completion_tokens=completion_tokens,
            total_tokens=prompt_tokens + completion_tokens,
        )
        setattr(model_response, "usage", usage)
        return model_response

View on GitHub (pinned to 6c2dcb801b)

Solutions

  1. Inspect the exception message — it is json.dumps of the full upstream body, showing exactly which shape came back.
  2. Match your call mode to the engine (non-streaming completion vs streaming) as documented for that engine.
  3. Pin/verify the engine name and NLP Cloud API version you coded against.
  4. If the shape changed upstream, update litellm to the latest version which may already handle it.

Example fix

# before
out = litellm.completion(model="nlp_cloud/finetuned-llama-3-70b", messages=msgs)  # shape drift crashes parse

# after — surface the raw body for diagnosis and degrade gracefully
from litellm.exceptions import APIError
try:
    out = litellm.completion(model="nlp_cloud/finetuned-llama-3-70b", messages=msgs)
except APIError as e:
    log.error("nlp_cloud unexpected body: %s", e)
    raise
Defensive patterns

Strategy: try-catch

Try / catch

from litellm.exceptions import APIError
try:
    out = litellm.completion(model="nlp_cloud/finetuned-llama-3-70b", messages=msgs)
except APIError as e:
    # message is json.dumps of the raw body — log it and alert, shape changed upstream
    log.error("nlp_cloud unexpected response shape: %s", e)
    raise

Prevention

When it happens

Trigger: Calling litellm.completion() with nlp_cloud/* where the JSON body lacks generated_text: an unexpected status shape (e.g. an async job acknowledgement), a changed API contract after an NLP Cloud update, or a gateway JSON error without an "error" key.

Common situations: NLP Cloud API changes/updates altering response shape, using a completion model with a stream-style response while streaming is off, or account-level notices returned as JSON.

Related errors


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