{"record":{"id":"b56724963868014e","repo":"Hmbown/CodeWhale","slug":"fleet-alert-url-name-is-not-configured","errorCode":null,"errorMessage":"fleet alert URL {name} is not configured","messagePattern":"fleet alert URL (.+?) is not configured","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"crates/tui/src/fleet/alerts.rs","lineNumber":498,"sourceCode":"    }\n}\n\nfn required_secret<R>(resolver: &R, name: &str) -> Result<String>\nwhere\n    R: FleetAlertSecretResolver,\n{\n    resolver\n        .resolve(name)\n        .ok_or_else(|| anyhow!(\"fleet alert secret {name} is not configured\"))\n}\n\nfn required_https_url<R>(resolver: &R, name: &str) -> Result<String>\nwhere\n    R: FleetAlertSecretResolver,\n{\n    let url = resolver\n        .resolve(name)\n        .ok_or_else(|| anyhow!(\"fleet alert URL {name} is not configured\"))?;\n    validate_https_alert_url(name, &url)?;\n    Ok(url)\n}\n\nfn validate_https_alert_url(name: &str, url: &str) -> Result<()> {\n    let parsed = reqwest::Url::parse(url)\n        .with_context(|| format!(\"fleet alert URL from {name} is not a valid URL\"))?;\n    if parsed.scheme() != \"https\" {\n        return Err(anyhow!(\"fleet alert URL from {name} must use https\"));\n    }\n    Ok(())\n}\n\nfn short_reason(reason: &str) -> String {\n    let trimmed = reason.trim();\n    if trimmed.len() <= 240 {\n        return trimmed.to_string();\n    }","sourceCodeStart":480,"sourceCodeEnd":516,"githubUrl":"https://github.com/Hmbown/CodeWhale/blob/0c42157ee52f9d55af2b506d71b46249910f77d3/crates/tui/src/fleet/alerts.rs#L480-L516","documentation":"required_https_url() resolves a Webhook alert adapter's url_env variable through the secret resolver (env var, non-empty required). If the variable is absent or empty, resolve returns None and this error fires, naming the expected env var. It fires before URL syntax or scheme checks, so a set-but-malformed URL produces a different error.","triggerScenarios":"A Webhook adapter (kind: webhook with url_env: \"FLEET_WEBHOOK_URL\") dispatched with dry_run=false while FLEET_WEBHOOK_URL is unset, exported as empty, or defined only in a parent shell the process never inherited.","commonSituations":"Secrets managed per-shell but fleet runs from a daemon, launcher, or CI job; renaming the env var in config without updating deployment environment; multiple webhook adapters sharing one url_env name where one deployment forgot it.","solutions":["Export a non-empty HTTPS URL under the exact name in url_env in the process environment that dispatches alerts.","Check 'env | grep <name>' inside that same context (systemd 'Environment=', tmux session, CI secret) rather than your editor shell.","Keep dry_run=true in environments that intentionally have no webhook target — dry-run does not hit the URL requirement path the same way.","If multiple adapters need the same endpoint, point all url_env fields at one variable name and set it once."],"exampleFix":"# before\n# adapters: {\"hook\":{\"kind\":\"webhook\",\"url_env\":\"ALERT_HOOK_URL\"}}\n$ ./run-fleet.sh        # ALERT_HOOK_URL unset -> error\n\n# after\n$ ALERT_HOOK_URL=\"https://hooks.example.com/fleet\" ./run-fleet.sh","handlingStrategy":"validation","validationCode":"fn webhook_urls_resolvable(cfg: &FleetAlertConfig) -> Result<(), String> {\n    for (name, adapter) in &cfg.adapters {\n        if let FleetAlertAdapterConfig::Webhook { url_env, .. } = adapter {\n            if std::env::var(url_env).map(|v| v.is_empty()).unwrap_or(true) {\n                return Err(format!(\"webhook adapter '{name}' needs non-empty env {url_env}\"));\n            }\n        }\n    }\n    Ok(())\n}\n","typeGuard":null,"tryCatchPattern":"match dispatcher.dispatch(&event) {\n    Err(e) if e.to_string().contains(\"URL\") && e.to_string().contains(\"not configured\") => {\n        // env var named in message is missing in this process; log and degrade (skip alert)\n    }\n    other => other.map(|_| ())?,\n}","preventionTips":["Centralize webhook URL env var names in one constants module referenced by config generation.","Smoke-test env inheritance with 'env | grep <url_env>' inside the exact runtime context.","Automate provisioning so every environment that enables webhooks sets the URL var.","Consider a custom FleetAlertSecretResolver backed by a secret store so absence is detected at construction."],"tags":["fleet","alerts","webhook","environment","env-var"],"backgroundTag":"missing-env-var","analyzedSha":"0c42157ee52f9d55af2b506d71b46249910f77d3","analyzedAt":"2026-08-20T21:50:45.477Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}