{"record":{"id":"11e7bfb3c16dd803","repo":"BerriAI/litellm","slug":"credentials-are-none-after-loading","errorCode":null,"errorMessage":"Credentials are None after loading","messagePattern":"Credentials are None after loading","errorType":"exception","errorClass":"ValueError","httpStatus":null,"severity":"error","filePath":"litellm/llms/vertex_ai/vertex_llm_base.py","lineNumber":933,"sourceCode":"                _credentials,\n                credential_project_id,\n            )\n\n        ## VALIDATE CREDENTIALS\n        verbose_logger.debug(\"Validating credentials\")\n        if project_id is None and credential_project_id is not None and isinstance(credential_project_id, str):\n            project_id = credential_project_id\n            # Update cache with resolved project_id for future lookups\n            resolved_cache_key: Final = (cache_credentials, project_id)\n            if resolved_cache_key not in self._credentials_project_mapping:\n                self._credentials_project_mapping[resolved_cache_key] = (\n                    _credentials,\n                    credential_project_id,\n                )\n\n        # Check if credentials are None before accessing attributes\n        if _credentials is None:\n            raise ValueError(\"Credentials are None after loading\")\n\n        if _credentials.expired:\n            with self._sync_refresh_lock:\n                # Double-check after acquiring lock\n                if _credentials.expired:\n                    try:\n                        verbose_logger.debug(\"Credentials expired, refreshing\")\n                        self.refresh_auth(_credentials)\n                        self._credentials_project_mapping[credential_cache_key] = (\n                            _credentials,\n                            credential_project_id,\n                        )\n                    except Exception as e:\n                        # if refresh fails, it's possible the user has re-authenticated via `gcloud auth application-default login`\n                        # in this case, we should try to reload the credentials by clearing the cache and retrying\n                        if \"Reauthentication is needed\" in str(e) and not _retry_reauth:\n                            return self._handle_reauthentication(\n                                credentials=credentials,","sourceCodeStart":915,"sourceCodeEnd":951,"githubUrl":"https://github.com/BerriAI/litellm/blob/77b7c6c40c0c5aa5fbcb1d6a1825ac39ca8829b8/litellm/llms/vertex_ai/vertex_llm_base.py#L915-L951","documentation":"A defensive check in `get_access_token` that fires when the credentials variable is still None after the cache lookup, project-id fallback, and load_auth path — i.e. the code is about to dereference `_credentials.expired` on a None object. Practically it means a None credentials entry came back from the per-instance `_credentials_project_mapping` cache (or load_auth quietly returned None), so the stored mapping is unusable. It guards against an AttributeError and surfaces the real problem: no live credentials for this cache key.","triggerScenarios":"Repeated calls on the same VertexBase handler instance where an earlier lookup cached a None result for (credentials, project_id); or a race where the cached credentials object was replaced with None; or load_auth returning None without raising (partial/invalid credentials dict).","commonSituations":"Long-lived LiteLLM proxy processes after credentials were removed from the environment mid-flight; tests that reuse handler instances with monkeypatched load_auth; passing `vertex_credentials={}` (empty dict) which fails JSON serialization into a real credentials object.","solutions":["Restart the process (or proxy worker) so the credentials cache `_credentials_project_mapping` is rebuilt from a valid source.","Supply complete, valid credentials for the next call: vertex_credentials=<full sa.json string>, vertex_project=<id>, so a fresh cache key is used.","If it persists, run with verbose logging to see the load_auth exception that produced the None entry, and fix the credential source (ADC login / env var / key file).","Upgrade litellm — credential-cache handling around None entries has been tightened in newer releases."],"exampleFix":null,"handlingStrategy":"retry","validationCode":null,"typeGuard":null,"tryCatchPattern":"try:\n    litellm.completion(model=\"vertex_ai/...\", messages=msgs, vertex_credentials=sa_json)\nexcept ValueError as e:\n    if \"Credentials are None after loading\" in str(e):\n        # stale in-process credential cache: recycle the worker / process\n        os._exit(1)  # let the supervisor restart with clean state\n    raise","preventionTips":["Recycle long-lived workers on a schedule so the in-memory credential cache cannot pin a bad state.","Pass full, valid vertex_credentials per call in multi-tenant setups so each tenant gets its own cache key.","Never pass empty dicts/strings as credentials; validate JSON parses before handing it to litellm."],"tags":["vertex-ai","credentials","cache","defensive-check"],"backgroundTag":"gcp-credentials-not-found","analyzedSha":"77b7c6c40c0c5aa5fbcb1d6a1825ac39ca8829b8","analyzedAt":"2026-08-18T11:44:31.656Z","schemaVersion":2},"datasetVersion":"2026-08-27T08:17:20.692Z"}