{"record":{"id":"5dbe2bc769b2acdb","repo":"BerriAI/litellm","slug":"api-key-is-required-in-litellm-params-for-wxo-ag","errorCode":null,"errorMessage":"'api_key' is required in litellm_params for WXO agents","messagePattern":"'api_key' is required in litellm_params for WXO agents","errorType":"validation","errorClass":"ValueError","httpStatus":null,"severity":"error","filePath":"litellm/a2a_protocol/providers/watsonx_orchestrate/handler.py","lineNumber":203,"sourceCode":"            if chunk_text:\n                accumulated_text += chunk_text\n        return accumulated_text\n\n    @staticmethod\n    def _extract_litellm_params(litellm_params: dict[str, Any]) -> WXORequestParams:\n        cp4d_host: Final = litellm_params.get(\"cp4d_host\") or \"\"\n        instance_id: Final = litellm_params.get(\"instance_id\") or \"\"\n        wxo_agent_id: Final = litellm_params.get(\"wxo_agent_id\") or \"\"\n        api_key: Final = litellm_params.get(\"api_key\") or \"\"\n\n        if not cp4d_host:\n            raise ValueError(\"'cp4d_host' is required in litellm_params for WXO agents\")\n        if not instance_id:\n            raise ValueError(\"'instance_id' is required in litellm_params for WXO agents\")\n        if not wxo_agent_id:\n            raise ValueError(\"'wxo_agent_id' is required in litellm_params for WXO agents\")\n        if not api_key:\n            raise ValueError(\"'api_key' is required in litellm_params for WXO agents\")\n\n        return WXORequestParams(\n            cp4d_host=cp4d_host,\n            instance_id=instance_id,\n            wxo_agent_id=wxo_agent_id,\n            api_key=api_key,\n            username=litellm_params.get(\"username\") or None,\n            auth_mode=litellm_params.get(\"auth_mode\") or \"cp4d\",\n            thread_id=litellm_params.get(\"thread_id\") or None,\n        )\n\n    @staticmethod\n    async def handle_non_streaming(\n        request_id: str,\n        params: dict[str, Any],\n        litellm_params: dict[str, Any],\n    ) -> dict[str, Any]:\n        wxo: Final = WatsonxOrchestrateHandler._extract_litellm_params(litellm_params)","sourceCodeStart":185,"sourceCodeEnd":221,"githubUrl":"https://github.com/BerriAI/litellm/blob/77b7c6c40c0c5aa5fbcb1d6a1825ac39ca8829b8/litellm/a2a_protocol/providers/watsonx_orchestrate/handler.py#L185-L221","documentation":"Every Watsonx Orchestrate call authenticates with an api_key (exchanged for a CP4D or IAM token), so _extract_litellm_params() requires a non-empty api_key in litellm_params. Missing or blank values raise this ValueError up front, before the token exchange. This is the credentials check for the WXO provider.","triggerScenarios":"A watsonx_orchestrate deployment without api_key in litellm_params; api_key: os.environ/WXO_API_KEY where the env var is not set in the proxy's environment; an empty string leaking through from a secrets template.","commonSituations":"Env var present locally but missing in the container/service running LiteLLM; secret managers failing to render the key in one environment; service-level API keys rotated and the old one deleted without updating the proxy.","solutions":["Add api_key (the CP4D/IAM service apikey) to the deployment's litellm_params","If referencing os.environ/WXO_API_KEY, export it in the environment where the proxy actually runs and restart","Verify the other required WXO keys are present in the same block","Never inline real keys in committed config — use env var indirection"],"exampleFix":"# before\nlitellm_params:\n  model: watsonx_orchestrate/my-agent\n  cp4d_host: https://cp4d.example.com\n  instance_id: 6c9b...\n  wxo_agent_id: my-agent-id\n\n# after\nlitellm_params:\n  model: watsonx_orchestrate/my-agent\n  cp4d_host: https://cp4d.example.com\n  instance_id: 6c9b...\n  wxo_agent_id: my-agent-id\n  api_key: os.environ/WXO_API_KEY   # ensure WXO_API_KEY is exported\n","handlingStrategy":"validation","validationCode":"import os\n\ndef validate_wxo_credentials() -> None:\n    if not os.environ.get(\"WXO_API_KEY\"):\n        raise RuntimeError(\"WXO_API_KEY not set; WXO agents cannot authenticate\")\n","typeGuard":null,"tryCatchPattern":"try:\n    result = await WatsonxOrchestrateHandler.handle_request(params)\nexcept ValueError as e:\n    if \"'api_key' is required\" in str(e):\n        raise HTTPException(500, \"WXO deployment missing api_key\") from e\n    raise\n","preventionTips":["Reference api_key via os.environ/... and assert the var at startup","Rotate WXO apikeys with overlap: add the new key to config before deleting the old one","Never commit api_key values; use secrets management"],"tags":["watsonx-orchestrate","api-key","credentials","configuration","required-param"],"backgroundTag":"missing-auth-credentials","analyzedSha":"77b7c6c40c0c5aa5fbcb1d6a1825ac39ca8829b8","analyzedAt":"2026-08-18T11:44:31.656Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}