{"record":{"id":"aecc297b688051bd","repo":"BerriAI/litellm","slug":"missing-slack-webhook-url-from-environment","errorCode":null,"errorMessage":"Missing SLACK_WEBHOOK_URL from environment","messagePattern":"Missing SLACK_WEBHOOK_URL from environment","errorType":"exception","errorClass":"ValueError","httpStatus":null,"severity":"error","filePath":"litellm/integrations/SlackAlerting/slack_alerting.py","lineNumber":1345,"sourceCode":"            return\n        if alert_type not in self.alert_types:\n            return\n\n        from datetime import datetime\n\n        # Check if digest mode is enabled for this alert type\n        alert_type_name_str: Final = getattr(alert_type, \"value\", str(alert_type))\n        _atc: Final = self.alert_type_config.get(alert_type_name_str)\n        if _atc is not None and _atc.digest:\n            # Resolve webhook URL for this alert type (needed for digest entry)\n            if self.alert_to_webhook_url is not None and alert_type in self.alert_to_webhook_url:\n                _digest_webhook: str | list[str] | None = self.alert_to_webhook_url[alert_type]\n            elif self.default_webhook_url is not None:\n                _digest_webhook = self.default_webhook_url\n            else:\n                _digest_webhook = os.getenv(\"SLACK_WEBHOOK_URL\", None)\n            if _digest_webhook is None:\n                raise ValueError(\"Missing SLACK_WEBHOOK_URL from environment\")\n\n            digest_key: Final = f\"{alert_type_name_str}:{request_model or ''}:{api_base or ''}\"\n\n            async with self.digest_lock:\n                now: Final = datetime.now()\n                if digest_key in self.digest_buckets:\n                    self.digest_buckets[digest_key][\"count\"] += 1\n                    self.digest_buckets[digest_key][\"last_time\"] = now\n                else:\n                    self.digest_buckets[digest_key] = DigestEntry(\n                        alert_type=alert_type_name_str,\n                        request_model=request_model or \"\",\n                        api_base=api_base or \"\",\n                        first_message=message,\n                        level=level,\n                        count=1,\n                        start_time=now,\n                        last_time=now,","sourceCodeStart":1327,"sourceCodeEnd":1363,"githubUrl":"https://github.com/BerriAI/litellm/blob/77b7c6c40c0c5aa5fbcb1d6a1825ac39ca8829b8/litellm/integrations/SlackAlerting/slack_alerting.py#L1327-L1363","documentation":"When an alert type is configured for digest mode (_atc.digest true), litellm resolves the webhook in priority order: self.alert_to_webhook_url[alert_type], then self.default_webhook_url, then os.getenv('SLACK_WEBHOOK_URL'). If all three are unset the digest bucket cannot record a target and a ValueError is raised mid-_async_send_alert (litellm/integrations/SlackAlerting/slack_alerting.py:1347-1361).","triggerScenarios":"Enabling a digest-mode alert type (e.g. db_exceptions/services/region-outage digests) via only the SLACK_WEBHOOK_URL env var while that env var is missing from the proxy process; configuring alert types without providing alerting webhook URLs in general_settings and without default_webhook_url; docker/k8s deployments where the env var is set in one container but alerts fire in another.","commonSituations":"Proxy config lists alert types under alerting: [...] assuming webhooks come from env, but the env var name is misspelled or unset in the deployment; moving from per-alert URLs to digest alerts without carrying the webhook config over.","solutions":["Set SLACK_WEBHOOK_URL in the proxy process environment and restart.","Or configure general_settings.alerting: [\"https://hooks.slack.com/services/...\"] so default_webhook_url is populated.","Or map the specific alert type in general_settings.alerting_to_webhook_url (litellm_settings.alert_to_webhook_url) so the per-type lookup hits.","Verify inside the container: docker exec <proxy> printenv SLACK_WEBHOOK_URL."],"exampleFix":"# before\n# litellm_config.yaml\nlitellm_settings:\nalerting: [\"spend_alerts\"]  # digest-mode type, no webhook anywhere\n# ValueError: Missing SLACK_WEBHOOK_URL from environment\n\n# after\nexport SLACK_WEBHOOK_URL=https://hooks.slack.com/services/T000/B000/XXXX\n# or in config:\ngeneral_settings:\n  alerting: [\"https://hooks.slack.com/services/T000/B000/XXXX\"]","handlingStrategy":"validation","validationCode":"import os\n\nwebhook = (\n    (alerting.alert_to_webhook_url or {}).get(alert_type)\n    or alerting.default_webhook_url\n    or os.getenv(\"SLACK_WEBHOOK_URL\")\n)\nif webhook is None:\n    raise RuntimeError(\"no webhook resolvable for digest alerts: set SLACK_WEBHOOK_URL or general_settings.alerting URLs\")","typeGuard":null,"tryCatchPattern":"try:\n    await alerting._async_send_alert(alert_type=..., message=msg)\nexcept ValueError as e:\n    if \"Missing SLACK_WEBHOOK_URL\" in str(e):\n        logger.warning(\"digest alert dropped: configure SLACK_WEBHOOK_URL or alerting webhook URLs\")\n    else:\n        raise","preventionTips":["Whenever you enable a digest-mode alert type, also define a webhook source (env var, general_settings.alerting URL, or per-type map).","Verify env inside the running container (printenv) after deploy.","Smoke-test one alert of each configured type at startup."],"tags":["litellm","slack-alerting","digest","webhook","environment-variable"],"backgroundTag":"missing-env-var","analyzedSha":"77b7c6c40c0c5aa5fbcb1d6a1825ac39ca8829b8","analyzedAt":"2026-08-18T11:44:31.656Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}