{"record":{"id":"afdca9867183538f","repo":"BerriAI/litellm","slug":"err-args-0","errorCode":null,"errorMessage":"{err.args[0]}","messagePattern":"\\{err\\.args\\[0\\]\\}","errorType":"http","errorClass":"GenAIHubOrchestrationError","httpStatus":400,"severity":"error","filePath":"litellm/llms/sap/chat/transformation.py","lineNumber":142,"sourceCode":"        temperature: int | None = None,\n        top_p: int | None = None,\n        response_format: dict | None = None,\n        tools: list | None = None,\n        tool_choice: str | dict | None = None,\n    ) -> None:\n        locals_: Final = locals().copy()\n        for key, value in locals_.items():\n            if key != \"self\" and value is not None:\n                setattr(self.__class__, key, value)\n        self.token_creator = None\n        self._base_url = None\n        self._resource_group = None\n\n    def run_env_setup(self, service_key: str | None = None) -> None:\n        try:\n            self.token_creator, self._base_url, self._resource_group = get_token_creator(service_key)\n        except ValueError as err:\n            raise GenAIHubOrchestrationError(status_code=400, message=err.args[0])\n\n    @property\n    def headers(self) -> dict[str, str]:\n        if self.token_creator is None:\n            self.run_env_setup()\n        access_token = self.token_creator()  # pyright: ignore[reportOptionalCall]  # run_env_setup set it or raised\n        return {\n            \"Authorization\": access_token,\n            \"AI-Resource-Group\": self.resource_group,\n            \"Content-Type\": \"application/json\",\n            \"AI-Client-Type\": \"LiteLLM\",\n        }\n\n    @property\n    def base_url(self) -> str:\n        if self._base_url is None:\n            self.run_env_setup()\n        return self._base_url","sourceCodeStart":124,"sourceCodeEnd":160,"githubUrl":"https://github.com/BerriAI/litellm/blob/77b7c6c40c0c5aa5fbcb1d6a1825ac39ca8829b8/litellm/llms/sap/chat/transformation.py#L124-L160","documentation":"Before the first SAP call, run_env_setup resolves credentials via get_token_creator; any ValueError from that chain (no credentials found in any source, missing auth_url/client_id/base_url, or an ambiguous auth mode - not exactly one of client_secret, cert pair, or cert files) is wrapped as GenAIHubOrchestrationError 400. The message names the exact credential problem.","triggerScenarios":"Calling litellm.completion(model='sap/...') with no AICORE_* environment variables, no AICORE_SERVICE_KEY, no ~/.aicore/config.json, and no service_key passed; or credentials that are incomplete (e.g. client_id and secret set but no AICORE_AUTH_URL/AICORE_BASE_URL); or multiple auth methods supplied at once (secret plus certificate).","commonSituations":"New environments where only some AICORE_* vars are exported; service keys pasted with missing fields; switching between secret-based and mTLS certificate auth and leaving both partially configured; k8s secrets mounted for a different profile than AICORE_PROFILE selects.","solutions":["Set the full secret-auth set: AICORE_CLIENT_ID, AICORE_CLIENT_SECRET, AICORE_AUTH_URL, AICORE_BASE_URL (and optionally AICORE_RESOURCE_GROUP).","Or pass the whole service key once: os.environ['AICORE_SERVICE_KEY'] = json.dumps(service_key_dict) or litellm.sap_service_key = service_key.","If using certificate auth, provide exactly one of cert_str+key_str or cert_file_path+key_file_path - and remove client_secret.","Check the wrapped message: 'No credentials found in any source' vs 'credentials are incomplete' tells you whether nothing or only partial config was found."],"exampleFix":"# before - incomplete env\nos.environ['AICORE_CLIENT_ID'] = '...'\n# after - complete secret auth\nos.environ['AICORE_CLIENT_ID'] = '...'\nos.environ['AICORE_CLIENT_SECRET'] = '...'\nos.environ['AICORE_AUTH_URL'] = 'https://<tenant>.authentication.sap.hana.ondemand.com/oauth/token'\nos.environ['AICORE_BASE_URL'] = 'https://api.ai.prod.eu-central-1.aws.ml.hana.ondemand.com/v2'","handlingStrategy":"validation","validationCode":"import os\n\nREQUIRED_ENV = ['AICORE_CLIENT_ID', 'AICORE_CLIENT_SECRET', 'AICORE_AUTH_URL', 'AICORE_BASE_URL']\nmissing = [k for k in REQUIRED_ENV if not os.environ.get(k)]\nif missing:\n    raise RuntimeError(f'SAP credentials incomplete, missing: {missing}')\nresp = litellm.completion(model='sap/...', messages=msgs)","typeGuard":null,"tryCatchPattern":"from litellm.llms.sap.chat.handler import GenAIHubOrchestrationError\n\ntry:\n    resp = litellm.completion(model='sap/gpt-4o', messages=msgs)\nexcept GenAIHubOrchestrationError as e:\n    if e.status_code == 400:\n        raise RuntimeError(f'SAP credential setup failed: {e.message}') from e\n    raise","preventionTips":["Export the full AICORE_* set from one secret manager entry so fields never drift apart.","Prefer AICORE_SERVICE_KEY with the complete service-key JSON over piecemeal env vars.","Add a startup credential check that calls fetch_credentials() before serving traffic."],"tags":["sap","generative-ai-hub","credentials","authentication"],"backgroundTag":"missing-credentials","analyzedSha":"77b7c6c40c0c5aa5fbcb1d6a1825ac39ca8829b8","analyzedAt":"2026-08-18T11:44:31.656Z","schemaVersion":2},"datasetVersion":"2026-08-27T08:17:20.692Z"}