{"record":{"id":"cdaa2d4b1400d12f","repo":"BerriAI/litellm","slug":"gray-swan-api-key-missing-set-grayswan-api-key","errorCode":null,"errorMessage":"Gray Swan API key missing. Set `GRAYSWAN_API_KEY` or pass `api_key`.","messagePattern":"Gray Swan API key missing\\. Set `GRAYSWAN_API_KEY` or pass `api_key`\\.","errorType":"validation","errorClass":"GraySwanGuardrailMissingSecrets","httpStatus":null,"severity":"critical","filePath":"litellm/proxy/guardrails/guardrail_hooks/grayswan/grayswan.py","lineNumber":84,"sourceCode":"        guardrail_name: str | None = \"grayswan\",\n        api_key: str | None = None,\n        api_base: str | None = None,\n        on_flagged_action: str | None = None,\n        violation_threshold: float | None = None,\n        reasoning_mode: str | None = None,\n        categories: dict[str, str] | None = None,\n        policy_id: str | None = None,\n        streaming_end_of_stream_only: bool = False,\n        streaming_sampling_rate: int = 5,\n        fail_open: bool | None = True,\n        guardrail_timeout: float | None = 30.0,\n        **kwargs: Any,\n    ) -> None:\n        self.async_handler = get_async_httpx_client(llm_provider=httpxSpecialProvider.GuardrailCallback)\n\n        api_key_value: Final = api_key or os.getenv(\"GRAYSWAN_API_KEY\")\n        if not api_key_value:\n            raise GraySwanGuardrailMissingSecrets(\n                \"Gray Swan API key missing. Set `GRAYSWAN_API_KEY` or pass `api_key`.\"\n            )\n        self.api_key: str = api_key_value\n\n        base: Final = api_base or os.getenv(\"GRAYSWAN_API_BASE\") or self.BASE_API_URL\n        self.api_base = base.rstrip(\"/\")\n        self.monitor_url = f\"{self.api_base}{self.MONITOR_PATH}\"\n\n        action: Final = on_flagged_action\n        if action and action.lower() in self.SUPPORTED_ON_FLAGGED_ACTIONS:\n            self.on_flagged_action = action.lower()\n        else:\n            if action:\n                verbose_proxy_logger.warning(\n                    \"Gray Swan Guardrail: Unsupported on_flagged_action '%s', defaulting to '%s'.\",\n                    action,\n                    self.DEFAULT_ON_FLAGGED_ACTION,\n                )","sourceCodeStart":66,"sourceCodeEnd":102,"githubUrl":"https://github.com/BerriAI/litellm/blob/77b7c6c40c0c5aa5fbcb1d6a1825ac39ca8829b8/litellm/proxy/guardrails/guardrail_hooks/grayswan/grayswan.py#L66-L102","documentation":"GraySwanGuardrailMissingSecrets raised in GraySwanGuardrail.__init__ when both the api_key parameter and the GRAYSWAN_API_KEY environment variable are empty. It is a dedicated exception (not plain ValueError) signaling missing credentials at guardrail construction time, before any monitor API call is attempted.","triggerScenarios":"A grayswan guardrail entry without api_key in litellm_params while GRAYSWAN_API_KEY is unset in the proxy process; secrets not mounted into the container/pod running the proxy.","commonSituations":"Local dev works (env var in shell) but the deployed proxy lacks the secret; secret rotated and the new value not propagated; docker-compose/K8s secret reference typo'd.","solutions":["Set GRAYSWAN_API_KEY in the proxy's runtime environment.","Or pass api_key: os.environ/GRAYSWAN_API_KEY in the guardrail's litellm_params.","Optionally set GRAYSWAN_API_BASE if your deployment uses a non-default base URL.","Restart the proxy after injecting the secret."],"exampleFix":"# before\nlitellm_params:\n  guardrail: grayswan\n  on_flagged_action: block\n\n# after\nlitellm_params:\n  guardrail: grayswan\n  on_flagged_action: block\n  api_key: os.environ/GRAYSWAN_API_KEY","handlingStrategy":"validation","validationCode":"import os\n\nif not (os.getenv('GRAYSWAN_API_KEY') or cfg.litellm_params.get('api_key')):\n    raise SystemExit('GRAYSWAN_API_KEY not set — refusing to start with grayswan guardrail')","typeGuard":"from litellm.proxy.guardrails.guardrail_hooks.grayswan.grayswan import GraySwanGuardrailMissingSecrets\n\ndef is_grayswan_missing_secrets(exc: BaseException) -> bool:\n    return isinstance(exc, GraySwanGuardrailMissingSecrets)","tryCatchPattern":"from litellm.proxy.guardrails.guardrail_hooks.grayswan.grayswan import GraySwanGuardrailMissingSecrets\ntry:\n    guardrail = GraySwanGuardrail(litellm_params=cfg)\nexcept GraySwanGuardrailMissingSecrets as e:\n    logger.error('deploy misconfigured: %s', e)\n    raise","preventionTips":["Store GRAYSWAN_API_KEY in a secret manager and inject it into the proxy's environment everywhere the config is loaded.","Add a startup assertion for required guardrail secrets.","Use os.environ/GRAYSWAN_API_KEY references instead of literal keys."],"tags":["grayswan","guardrail","api-key","secrets","startup"],"backgroundTag":"missing-env-var","analyzedSha":"77b7c6c40c0c5aa5fbcb1d6a1825ac39ca8829b8","analyzedAt":"2026-08-18T11:44:31.656Z","schemaVersion":2},"datasetVersion":"2026-08-21T18:17:14.833Z"}