{"record":{"id":"a614c42d736e7939","repo":"BerriAI/litellm","slug":"missing-cloudflare-account-id-set-cloudflare-acc","errorCode":null,"errorMessage":"Missing CLOUDFLARE_ACCOUNT_ID - set CLOUDFLARE_ACCOUNT_ID in the environment or pass api_base explicitly","messagePattern":"Missing CLOUDFLARE_ACCOUNT_ID - set CLOUDFLARE_ACCOUNT_ID in the environment or pass api_base explicitly","errorType":"validation","errorClass":"ValueError","httpStatus":null,"severity":"error","filePath":"litellm/llms/cloudflare/chat/transformation.py","lineNumber":53,"sourceCode":"        optional_params: dict,\n        litellm_params: dict,\n        stream: bool | None = None,\n    ) -> str:\n        return super().get_complete_url(\n            api_base=self._resolve_api_base(api_base),\n            api_key=api_key,\n            model=model,\n            optional_params=optional_params,\n            litellm_params=litellm_params,\n            stream=stream,\n        )\n\n    @staticmethod\n    def _resolve_api_base(api_base: str | None) -> str:\n        if not api_base:\n            account_id: Final = normalize_nonempty_secret_str(get_secret_str(\"CLOUDFLARE_ACCOUNT_ID\"))\n            if account_id is None:\n                raise ValueError(\n                    \"Missing CLOUDFLARE_ACCOUNT_ID - set CLOUDFLARE_ACCOUNT_ID in the environment or pass api_base explicitly\"\n                )\n            return f\"https://api.cloudflare.com/client/v4/accounts/{account_id}/ai/v1\"\n        trimmed: Final = api_base.rstrip(\"/\")\n        if trimmed.endswith(\"/ai/run\"):\n            verbose_logger.warning(\n                \"Cloudflare api_base ending in '/ai/run' is the legacy Workers AI path and no longer serves OpenAI-compatible requests; rewriting to the '/ai/v1' endpoint\"\n            )\n            return f\"{trimmed[: -len('/ai/run')]}/ai/v1\"\n        return api_base\n\n    def validate_environment(\n        self,\n        headers: dict,\n        model: str,\n        messages: list[AllMessageValues],\n        optional_params: dict,\n        litellm_params: dict,","sourceCodeStart":35,"sourceCodeEnd":71,"githubUrl":"https://github.com/BerriAI/litellm/blob/6c2dcb801bf2b75c18f1bb24140e7cf57465cc4d/litellm/llms/cloudflare/chat/transformation.py#L35-L71","documentation":"LiteLLM's Cloudflare Workers AI adapter builds the OpenAI-compatible endpoint URL from your Cloudflare account ID. When no api_base is passed and the CLOUDFLARE_ACCOUNT_ID environment variable is unset (or empty, which normalize_nonempty_secret_str treats as missing), _resolve_api_base raises this ValueError before any HTTP request is made. The account ID is required to construct 'https://api.cloudflare.com/client/v4/accounts/{account_id}/ai/v1'.","triggerScenarios":"Calling litellm.completion(model='cloudflare/...', ...) (or the async equivalent) without api_base while CLOUDFLARE_ACCOUNT_ID is not exported in the process environment; setting CLOUDFLARE_ACCOUNT_ID='' or to a whitespace-only string is also treated as missing.","commonSituations":"Deploying to a new environment (container, CI, serverless) where the Cloudflare env vars were not migrated; using a .env file that is not loaded by the runtime; passing only CLOUDFLARE_API_KEY and assuming the account ID is inferred from it.","solutions":["Export CLOUDFLARE_ACCOUNT_ID (your 32-hex-char Cloudflare account ID, visible in the Cloudflare dashboard URL) in the environment running LiteLLM.","Alternatively pass api_base explicitly, e.g. api_base='https://api.cloudflare.com/client/v4/accounts/<ACCOUNT_ID>/ai/v1'.","If using a .env file, confirm it is actually loaded (python-dotenv load_dotenv(), docker env_file, etc.) and that the variable name has no typos.","Verify with a quick check: python -c \"import os; print(os.environ.get('CLOUDFLARE_ACCOUNT_ID'))\" before starting the app."],"exampleFix":"# before\nos.environ.pop(\"CLOUDFLARE_ACCOUNT_ID\", None)\nresponse = litellm.completion(model=\"cloudflare/@cf/meta/llama-3.1-8b-instruct\", messages=[...])\n\n# after\nos.environ[\"CLOUDFLARE_ACCOUNT_ID\"] = \"abc123...\"  # from Cloudflare dashboard\nresponse = litellm.completion(model=\"cloudflare/@cf/meta/llama-3.1-8b-instruct\", messages=[...])","handlingStrategy":"validation","validationCode":"import os\n\naccount_id = os.environ.get(\"CLOUDFLARE_ACCOUNT_ID\", \"\").strip()\nif not account_id:\n    raise SystemExit(\"Set CLOUDFLARE_ACCOUNT_ID or pass api_base before calling cloudflare models\")","typeGuard":null,"tryCatchPattern":"try:\n    resp = litellm.completion(model=\"cloudflare/@cf/meta/llama-3.1-8b-instruct\", messages=msgs)\nexcept ValueError as e:\n    if \"CLOUDFLARE_ACCOUNT_ID\" in str(e):\n        # config problem: fail fast with actionable message, do not retry\n        raise","preventionTips":["Centralize provider config in one bootstrap module that asserts required env vars at startup.","Add a startup health check listing all provider env vars (CLOUDFLARE_ACCOUNT_ID, CLOUDFLARE_API_KEY) before serving traffic.","Store the account ID next to the API key in your secret manager so they are provisioned together."],"tags":["cloudflare","configuration","environment-variables","api-base"],"backgroundTag":null,"analyzedSha":"6c2dcb801bf2b75c18f1bb24140e7cf57465cc4d","analyzedAt":"2026-08-15T07:12:03.035Z","schemaVersion":2},"datasetVersion":"2026-08-15T17:31:12.345Z"}