BerriAI/litellm · error · ValueError
Missing SLACK_WEBHOOK_URL from environment
Error message
Missing SLACK_WEBHOOK_URL from environment
What it means
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).
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.
Example fix
# before # litellm_config.yaml litellm_settings: alerting: ["spend_alerts"] # digest-mode type, no webhook anywhere # ValueError: Missing SLACK_WEBHOOK_URL from environment # after export SLACK_WEBHOOK_URL=https://hooks.slack.com/services/T000/B000/XXXX # or in config: general_settings: alerting: ["https://hooks.slack.com/services/T000/B000/XXXX"]
Defensive patterns
Strategy: validation
Validate before calling
import os
webhook = (
(alerting.alert_to_webhook_url or {}).get(alert_type)
or alerting.default_webhook_url
or os.getenv("SLACK_WEBHOOK_URL")
)
if webhook is None:
raise RuntimeError("no webhook resolvable for digest alerts: set SLACK_WEBHOOK_URL or general_settings.alerting URLs") Try / catch
try:
await alerting._async_send_alert(alert_type=..., message=msg)
except ValueError as e:
if "Missing SLACK_WEBHOOK_URL" in str(e):
logger.warning("digest alert dropped: configure SLACK_WEBHOOK_URL or alerting webhook URLs")
else:
raise Prevention
- 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.
When it happens
Trigger: 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.
Common situations: 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.
Understand the failure class
Background: "environment variable is not set" and "Missing keys in environment" errors: what missing required env var messages mean and how to fix them — this error's family across 28 libraries.
Related errors
- Invalid webhook url value for
- Missing webhook_url from environment
- API key is required
- api_key is required for Volcengine authentication
- Cannot migrate covered tables: no salt key / master key is…
AI-assisted analysis of BerriAI/litellm@77b7c6c40c (2026-08-18).
Data as JSON: /api/errors/aecc297b688051bd.
Report an issue: GitHub.
Appendix: source
Thrown at litellm/integrations/SlackAlerting/slack_alerting.py:1345
return
if alert_type not in self.alert_types:
return
from datetime import datetime
# Check if digest mode is enabled for this alert type
alert_type_name_str: Final = getattr(alert_type, "value", str(alert_type))
_atc: Final = self.alert_type_config.get(alert_type_name_str)
if _atc is not None and _atc.digest:
# Resolve webhook URL for this alert type (needed for digest entry)
if self.alert_to_webhook_url is not None and alert_type in self.alert_to_webhook_url:
_digest_webhook: str | list[str] | None = self.alert_to_webhook_url[alert_type]
elif self.default_webhook_url is not None:
_digest_webhook = self.default_webhook_url
else:
_digest_webhook = os.getenv("SLACK_WEBHOOK_URL", None)
if _digest_webhook is None:
raise ValueError("Missing SLACK_WEBHOOK_URL from environment")
digest_key: Final = f"{alert_type_name_str}:{request_model or ''}:{api_base or ''}"
async with self.digest_lock:
now: Final = datetime.now()
if digest_key in self.digest_buckets:
self.digest_buckets[digest_key]["count"] += 1
self.digest_buckets[digest_key]["last_time"] = now
else:
self.digest_buckets[digest_key] = DigestEntry(
alert_type=alert_type_name_str,
request_model=request_model or "",
api_base=api_base or "",
first_message=message,
level=level,
count=1,
start_time=now,
last_time=now,View on GitHub (pinned to 77b7c6c40c)