BerriAI/litellm · error · ValueError
'api_key' is required in litellm_params for WXO agents
Error message
'api_key' is required in litellm_params for WXO agents
What it means
Configuration validation error from the WXO handler: 'api_key' is missing or empty in litellm_params. The api_key is the CP4D/WXO credential used for authentication, so the handler refuses to proceed without it rather than sending an unauthenticated request that would 401.
Source
Thrown at litellm/a2a_protocol/providers/watsonx_orchestrate/handler.py:203
if chunk_text:
accumulated_text += chunk_text
return accumulated_text
@staticmethod
def _extract_litellm_params(litellm_params: dict[str, Any]) -> WXORequestParams:
cp4d_host: Final = litellm_params.get("cp4d_host") or ""
instance_id: Final = litellm_params.get("instance_id") or ""
wxo_agent_id: Final = litellm_params.get("wxo_agent_id") or ""
api_key: Final = litellm_params.get("api_key") or ""
if not cp4d_host:
raise ValueError("'cp4d_host' is required in litellm_params for WXO agents")
if not instance_id:
raise ValueError("'instance_id' is required in litellm_params for WXO agents")
if not wxo_agent_id:
raise ValueError("'wxo_agent_id' is required in litellm_params for WXO agents")
if not api_key:
raise ValueError("'api_key' is required in litellm_params for WXO agents")
return WXORequestParams(
cp4d_host=cp4d_host,
instance_id=instance_id,
wxo_agent_id=wxo_agent_id,
api_key=api_key,
username=litellm_params.get("username") or None,
auth_mode=litellm_params.get("auth_mode") or "cp4d",
thread_id=litellm_params.get("thread_id") or None,
)
@staticmethod
async def handle_non_streaming(
request_id: str,
params: dict[str, Any],
litellm_params: dict[str, Any],
) -> dict[str, Any]:
wxo: Final = WatsonxOrchestrateHandler._extract_litellm_params(litellm_params)View on GitHub (pinned to 6c2dcb801b)
Solutions
- Add 'api_key' to litellm_params (in the proxy, use os.environ/WATSONX_APIKEY-style indirection so the secret is not hardcoded).
- If auth_mode is 'iam', ensure 'username' is also set and the api_key is the IAM key.
- Restart the LiteLLM proxy after config changes so params are re-read.
Example fix
# before litellm_params: model: watsonx_orchestrate/agent cp4d_host: https://cpd.example.com:443 instance_id: 1f2a3b4c-... wxo_agent_id: my-agent-id # after litellm_params: model: watsonx_orchestrate/agent cp4d_host: https://cpd.example.com:443 instance_id: 1f2a3b4c-... wxo_agent_id: my-agent-id api_key: os.environ/WATSONX_APIKEY
Defensive patterns
Strategy: validation
Validate before calling
def validate_wxo_config(litellm_params: dict) -> None:
missing = [k for k in ("cp4d_host", "instance_id", "wxo_agent_id", "api_key") if not litellm_params.get(k)]
if missing:
raise ConfigError(f"WXO config missing: {missing}") Type guard
def has_valid_wxo_config(p: dict) -> bool:
return all(isinstance(p.get(k), str) and p[k].strip() for k in ("cp4d_host", "instance_id", "wxo_agent_id", "api_key")) Prevention
- Reference the key via env indirection (os.environ/WATSONX_APIKEY) rather than hardcoding.
- Rotate CP4D API keys on a schedule and update the env var, not the config file.
- Add a startup smoke test that makes one cheap WXO call to validate all four params end to end.
When it happens
Trigger: WXO model config omitting 'api_key' or with an empty value. Runs last among the four ordered checks, so cp4d_host, instance_id, and wxo_agent_id must already be present. For SaaS-style auth_mode ('iam'), this key is still required by this validation.
Common situations: Expecting LiteLLM to pull the key from WATSONX_APIKEY env var automatically (it does not for this path — it must be in litellm_params); expired or rotated CP4D API key pasted as empty; secrets manager reference not resolved.
Related errors
- 'cp4d_host' is required in litellm_params for WXO agents
- 'instance_id' is required in litellm_params for WXO agents
- 'wxo_agent_id' is required in litellm_params for WXO agents
- workspace, repository, and access_token are required
- Error: {response.status_code} - {response.text}
AI-assisted analysis of BerriAI/litellm@6c2dcb801b (2026-08-15).
Data as JSON: /api/errors/5dbe2bc769b2acdb.
Report an issue: GitHub.