{"record":{"id":"a246b38b3c091fa4","repo":"Hmbown/CodeWhale","slug":"fleet-alert-url-name-is-not-configured-alerts","errorCode":null,"errorMessage":"Fleet alert URL {name} is not configured","messagePattern":"Fleet alert URL (.+?) is not configured","errorType":"exception","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/73e0f67d83c59909b571efdfc88c4bc28c309cb1/crates/tui/src/fleet/alerts.rs#L480-L516","documentation":"Adapters that post to a URL call `required_https_url`, which resolves the URL from the secret resolver and then validates it as https. If the resolver has no value for the named URL secret, the alert cannot be delivered and this error is thrown before any network call.","triggerScenarios":"Calling `send_alert` for an adapter whose endpoint URL (e.g. FLEET_SLACK_WEBHOOK_URL) is absent from the resolver when `required_https_url` is invoked.","commonSituations":"Webhook URL secret never configured in the environment; URL stored under a different name than the adapter expects; secrets mounted only in a different deployment stage.","solutions":["Set the named URL secret (e.g. a webhook URL) in the resolver's backing store.","Confirm the name matches the adapter's expected URL key exactly.","Use `codewhale`'s dry-run/diagnostic output to list which secrets the adapter requires, then supply them."],"exampleFix":"// before\n# no FLEET_SLACK_WEBHOOK_URL set\n// after\nexport FLEET_SLACK_WEBHOOK_URL=https://hooks.slack.com/services/...","handlingStrategy":"validation","validationCode":"fn ensure_alert_urls(names: &[&str]) -> Result<()> {\n    for name in names {\n        let url = std::env::var(name).map_err(|_| anyhow!(\"missing alert URL {name}\"))?;\n        anyhow::ensure!(url.starts_with(\"https://\"), \"alert URL {name} must be https\");\n    }\n    Ok(())\n}","typeGuard":null,"tryCatchPattern":"match send_alert(adapter, &prepared).await {\n    Err(e) if e.to_string().contains(\"URL\") && e.to_string().contains(\"not configured\") => {\n        log::error!(\"cannot deliver alert, endpoint URL missing: {e}\");\n    }\n    other => other?,\n}","preventionTips":["Provision webhook URL secrets alongside adapter config and verify at startup.","Document each adapter's expected URL secret name.","Use dry-run mode to confirm all URLs resolve before enabling real sends."],"tags":["fleet","alerts","url","secrets"],"backgroundTag":"missing-env-var","analyzedSha":"73e0f67d83c59909b571efdfc88c4bc28c309cb1","analyzedAt":"2026-09-22T01:30:00.501Z","contentChangedAt":"2026-09-22T01:30:00.501Z","schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}