{"record":{"id":"3e153c2c3218c8ec","repo":"openai/openai-python","slug":"unable-to-handle-auth","errorCode":null,"errorMessage":"Unable to handle auth","messagePattern":"Unable to handle auth","errorType":"validation","errorClass":"ValueError","httpStatus":null,"severity":"error","filePath":"src/openai/lib/azure.py","lineNumber":496,"sourceCode":"            self._refresh_api_key()\n\n        headers: dict[str, str | Omit] = {**options.headers} if is_given(options.headers) else {}\n\n        options = model_copy(options)\n        options.headers = headers\n\n        azure_ad_token = self._get_azure_ad_token()\n        if azure_ad_token is not None:\n            if not _has_header(headers, \"Authorization\"):\n                headers[\"Authorization\"] = f\"Bearer {azure_ad_token}\"\n        elif self.api_key and self.api_key != API_KEY_SENTINEL:\n            if not _has_header(headers, \"api-key\"):\n                headers[\"api-key\"] = self.api_key\n        elif _has_auth_header(headers) or _has_auth_header(self.default_headers):\n            pass\n        else:\n            # should never be hit\n            raise ValueError(\"Unable to handle auth\")\n\n        return options\n\n    def _configure_realtime(self, model: str, extra_query: Query) -> tuple[httpx2.URL, dict[str, str]]:\n        auth_headers = {}\n        query = {\n            **extra_query,\n            \"api-version\": self._api_version,\n            \"deployment\": self._azure_deployment or model,\n        }\n        if self.api_key and self.api_key != \"<missing API key>\":\n            auth_headers = {\"api-key\": self.api_key}\n        else:\n            token = self._get_azure_ad_token()\n            if token:\n                auth_headers = {\"Authorization\": f\"Bearer {token}\"}\n\n        if self.websocket_base_url is not None:","sourceCodeStart":478,"sourceCodeEnd":514,"githubUrl":"https://github.com/openai/openai-python/blob/9917c6e28e66e90e1227b3d223c06a8c5441515a/src/openai/lib/azure.py#L478-L514","documentation":"An internal invariant in _prepare_options: the request had neither an api-key header, nor an api-key-bearing client, nor an Authorization header. The comment says it 'should never be hit', so hitting it indicates corrupted client state or a custom subclass interfering with auth header generation.","triggerScenarios":"Mutating client.auth/default_headers after construction to remove auth, subclassing AzureOpenAI and overriding _prepare_options/_auth_headers incorrectly, or a custom api_key provider returning a value that bypasses the api-key branch.","commonSituations":"Essentially unreachable in normal use; appears only with subclasses or direct header manipulation.","solutions":["Avoid mutating default_headers to strip Authorization/api-key; construct a new client instead","If subclassing, ensure _auth_headers/_prepare_options overrides preserve the contract","Report as a bug if reproducible with the unmodified client"],"exampleFix":null,"handlingStrategy":"try-catch","validationCode":null,"typeGuard":null,"tryCatchPattern":"try:\n    client.chat.completions.create(...)\nexcept ValueError as e:\n    if str(e) == \"Unable to handle auth\":\n        rebuild_client_with_fresh_auth()\n    raise","preventionTips":["Don't strip auth headers at runtime","Avoid overriding internal auth methods in subclasses"],"tags":["azure","internal-invariant","unreachable","subclassing"],"backgroundTag":"internal-invariant-violation","analyzedSha":"9917c6e28e66e90e1227b3d223c06a8c5441515a","analyzedAt":"2026-08-28T11:46:34.183Z","schemaVersion":2},"datasetVersion":"2026-08-28T16:17:29.566Z"}