BerriAI/litellm · error · WatsonXAIError

Error: Watsonx project_id and space_id not set. Set WX_PROJE

Error message

Error: Watsonx project_id and space_id not set. Set WX_PROJECT_ID or WX_SPACE_ID in environment variables or pass in as a parameter.

What it means

WatsonX requires scoping every request to a project or a deployment space. _get_api_params resolves project_id from params (project_id / watsonx_project) or env (WATSONX_PROJECT_ID / WX_PROJECT_ID / PROJECT_ID), and space_id from params or env (WATSONX_DEPLOYMENT_SPACE_ID / WATSONX_SPACE_ID / WX_SPACE_ID / SPACE_ID). If both are None, a model is given, and the model is not a 'deployment/...' id, this WatsonXAIError (401) is raised before the request.

Source

Thrown at litellm/llms/watsonx/common_utils.py:111

        )  # consistent with how vertex ai + aws regions are accepted

    # Load auth variables from environment variables
    if project_id is None:
        project_id = (
            get_secret_str("WATSONX_PROJECT_ID") or get_secret_str("WX_PROJECT_ID") or get_secret_str("PROJECT_ID")
        )
    if region_name is None:
        region_name = get_secret_str("WATSONX_REGION") or get_secret_str("WX_REGION") or get_secret_str("REGION")
    if space_id is None:
        space_id = (
            get_secret_str("WATSONX_DEPLOYMENT_SPACE_ID")
            or get_secret_str("WATSONX_SPACE_ID")
            or get_secret_str("WX_SPACE_ID")
            or get_secret_str("SPACE_ID")
        )

    if project_id is None and space_id is None and model is not None and not model.startswith("deployment/"):
        raise WatsonXAIError(
            status_code=401,
            message="Error: Watsonx project_id and space_id not set. Set WX_PROJECT_ID or WX_SPACE_ID in environment variables or pass in as a parameter.",
        )

    return WatsonXAPIParams(
        project_id=project_id,
        space_id=space_id,
        region_name=region_name,
    )


async def _aconvert_watsonx_messages_core(
    model: str,
    messages: list[AllMessageValues],
    provider: str,
    custom_prompt_dict: dict,
    apply_template_fn,
) -> str:

View on GitHub (pinned to 77b7c6c40c)

Solutions

  1. export WX_PROJECT_ID=<your-project-id> (or WATSONX_PROJECT_ID / PROJECT_ID).
  2. Or pass project_id as a call param: litellm.completion(..., project_id=...).
  3. For deployed models, use model="deployment/<deployment-id>" and set space_id instead.
  4. In the proxy, put project_id in the watsonx model's litellm_params.

Example fix

# before
resp = litellm.completion(model="watsonx/meta-llama/llama-3-8b-instruct", messages=[{"role": "user", "content": "hi"}])
# -> WatsonXAIError: project_id and space_id not set

# after
resp = litellm.completion(
    model="watsonx/meta-llama/llama-3-8b-instruct",
    messages=[{"role": "user", "content": "hi"}],
    project_id=os.environ["WX_PROJECT_ID"],
)
Defensive patterns

Strategy: validation

Validate before calling

import os

project_id = os.getenv("WATSONX_PROJECT_ID") or os.getenv("WX_PROJECT_ID")
space_id = os.getenv("WATSONX_SPACE_ID") or os.getenv("WX_SPACE_ID")
if not project_id and not space_id and not model.startswith("deployment/"):
    raise RuntimeError("WatsonX needs WX_PROJECT_ID or WX_SPACE_ID for non-deployment models")
resp = litellm.completion(model=model, messages=msgs, project_id=project_id)

Type guard

const isDeploymentModel = (model: string): boolean => model.startsWith("deployment/");

const watsonxScoped = (model: string, env: Record<string, string | undefined>): boolean =>
  isDeploymentModel(model) || Boolean(env.WX_PROJECT_ID ?? env.WX_SPACE_ID ?? env.WATSONX_PROJECT_ID);

Try / catch

from litellm.llms.watsonx.common_utils import WatsonXAIError

try:
    resp = litellm.completion(model=model, messages=msgs)
except WatsonXAIError as e:
    if "project_id and space_id not set" in e.message:
        raise RuntimeError("Set WX_PROJECT_ID (or WX_SPACE_ID) for WatsonX foundation models") from e
    raise

Prevention

When it happens

Trigger: litellm.completion(model="watsonx/meta-llama/llama-3-8b-instruct", ...) with no project_id/space_id anywhere; env vars named PROJECT_ID set to empty string in some shells; calling a base model instead of a deployed one without scoping.

Common situations: Copying model calls from IBM docs without copying the project setup; per-tenant processes where PROJECT_ID is set only for some tenants; switching from deployment models (which bypass the check) to foundation models.

Understand the failure class

Background: "X is required", "must be set", "cannot be empty": the missing-required-config error family, from Vertex AI project/location to WeChat keys — this error's family across 18 libraries.

Related errors


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