{"record":{"id":"78ca9374ab6284cf","repo":"BerriAI/litellm","slug":"deepkeep-api-base-url-is-required-set-the-deepke","errorCode":null,"errorMessage":"DeepKeep API base URL is required. Set the `DEEPKEEP_API_BASE` environment variable or pass `api_base` in the guardrail config.","messagePattern":"DeepKeep API base URL is required\\. Set the `DEEPKEEP_API_BASE` environment variable or pass `api_base` in the guardrail config\\.","errorType":"exception","errorClass":"DeepKeepGuardrailMissingSecrets","httpStatus":null,"severity":"error","filePath":"litellm/proxy/guardrails/guardrail_hooks/deepkeep/deepkeep.py","lineNumber":97,"sourceCode":"        if not deepkeep_api_key:\n            raise DeepKeepGuardrailMissingSecrets(\n                \"DeepKeep API key is required. Set the `DEEPKEEP_API_KEY` environment \"\n                \"variable or pass `api_key` in the guardrail config.\"\n            )\n        self.deepkeep_api_key: str = deepkeep_api_key\n\n        # Firewall ID\n        self.firewall_id = firewall_id or os.environ.get(\"DEEPKEEP_FIREWALL_ID\")\n        if not self.firewall_id:\n            raise DeepKeepGuardrailMissingSecrets(\n                \"DeepKeep firewall_id is required. Set the `DEEPKEEP_FIREWALL_ID` environment \"\n                \"variable or pass `deepkeep_firewall_id` in the guardrail config.\"\n            )\n\n        # API base URL\n        base_url = api_base or os.environ.get(\"DEEPKEEP_API_BASE\")\n        if not base_url:\n            raise DeepKeepGuardrailMissingSecrets(\n                \"DeepKeep API base URL is required. Set the `DEEPKEEP_API_BASE` environment \"\n                \"variable or pass `api_base` in the guardrail config.\"\n            )\n\n        # Normalize the API base – ensure it ends with the guardrail endpoint\n        base_url = base_url.rstrip(\"/\")\n        if base_url.endswith(_DEEPKEEP_GUARDRAIL_ENDPOINT.rstrip(\"/\")):\n            self.api_base = base_url\n        else:\n            self.api_base = f\"{base_url}{_DEEPKEEP_GUARDRAIL_ENDPOINT}\"\n\n        self.unreachable_fallback: Literal[\"fail_closed\", \"fail_open\"] = unreachable_fallback\n        if extra_headers is not None and not isinstance(extra_headers, Mapping):\n            verbose_proxy_logger.warning(\n                \"DeepKeep guardrail ignoring `extra_headers`: expected a mapping of header name to value, got %s. \"\n                \"`litellm_params.extra_headers` is a list of header names to forward and is not supported by this guardrail\",\n                type(extra_headers).__name__,\n            )","sourceCodeStart":79,"sourceCodeEnd":115,"githubUrl":"https://github.com/BerriAI/litellm/blob/77b7c6c40c0c5aa5fbcb1d6a1825ac39ca8829b8/litellm/proxy/guardrails/guardrail_hooks/deepkeep/deepkeep.py#L79-L115","documentation":"DeepKeepGuardrailMissingSecrets raised by DeepKeepGuardrail.__init__ when no API base URL is available: neither the api_base argument nor the DEEPKEEP_API_BASE environment variable is set. The constructor then normalizes whatever base it gets (trailing slash stripped, the guardrail endpoint path appended if missing), so you only need to supply the plain tenant base URL.","triggerScenarios":"A deepkeep guardrails entry that supplies api_key and firewall_id but omits api_base while DEEPKEEP_API_BASE is unset in the proxy environment.","commonSituations":"Only key and firewall ID carried over from an example; per-environment base URL missing in prod manifests; pointing at the wrong tenant region host.","solutions":["Set DEEPKEEP_API_BASE to your DeepKeep tenant base URL (scheme + host; the guardrail endpoint path is appended automatically) and restart the proxy","Or add api_base: os.environ/DEEPKEEP_API_BASE under litellm_params","Do not manually append the guardrail endpoint path — the code appends it when missing, and appending twice is handled, but keep it simple","Verify network reachability of the base URL from the proxy container"],"exampleFix":"# before\nguardrails:\n  - guardrail_id: deepkeep\n    litellm_params:\n      mode: guardrail_runs_before_llm_call\n      api_key: os.environ/DEEPKEEP_API_KEY\n      deepkeep_firewall_id: os.environ/DEEPKEEP_FIREWALL_ID\n\n# after\n# export DEEPKEEP_API_BASE=https://your-tenant.deepkeep.ai\nguardrails:\n  - guardrail_id: deepkeep\n    litellm_params:\n      mode: guardrail_runs_before_llm_call\n      api_key: os.environ/DEEPKEEP_API_KEY\n      deepkeep_firewall_id: os.environ/DEEPKEEP_FIREWALL_ID\n      api_base: os.environ/DEEPKEEP_API_BASE","handlingStrategy":"validation","validationCode":"import os\nfrom urllib.parse import urlparse\n\nbase = os.environ.get('DEEPKEEP_API_BASE')\nif not base or not urlparse(base).scheme or not urlparse(base).netloc:\n    raise RuntimeError('DEEPKEEP_API_BASE must be set to a full URL (scheme + host)')","typeGuard":null,"tryCatchPattern":"from litellm.proxy.guardrails.guardrail_hooks.deepkeep.deepkeep import DeepKeepGuardrailMissingSecrets\ntry:\n    guardrail = DeepKeepGuardrail(\n        guardrail_name='deepkeep',\n        api_key=os.environ['DEEPKEEP_API_KEY'],\n        firewall_id=os.environ['DEEPKEEP_FIREWALL_ID'],\n    )\nexcept DeepKeepGuardrailMissingSecrets as e:\n    raise SystemExit(f'guardrail config incomplete: {e}') from e","preventionTips":["Supply the bare tenant base URL - the constructor appends the guardrail endpoint path itself","Keep per-environment base URLs (staging vs prod tenant) in env vars, not committed YAML","Check network egress from the proxy container to the base URL during deployment smoke tests"],"tags":["deepkeep","guardrails","base-url","environment-variables","litellm-proxy","startup-config"],"backgroundTag":"missing-required-config","analyzedSha":"77b7c6c40c0c5aa5fbcb1d6a1825ac39ca8829b8","analyzedAt":"2026-08-18T11:44:31.656Z","schemaVersion":2},"datasetVersion":"2026-08-27T08:17:20.692Z"}