{"record":{"id":"f64d93b1b4341422","repo":"Hmbown/CodeWhale","slug":"fleet-alert-secret-name-is-not-configured-alerts","errorCode":null,"errorMessage":"Fleet alert secret {name} is not configured","messagePattern":"Fleet alert secret (.+?) is not configured","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"crates/tui/src/fleet/alerts.rs","lineNumber":489,"sourceCode":"        FleetAlertEventClass::VerifierFailed => \"verifier_failed\",\n        FleetAlertEventClass::RunCompleted => \"run_completed\",\n    }\n}\n\nfn redacted_secret_header(secret_env: Option<&str>) -> Value {\n    match secret_env {\n        Some(name) => json!({ \"X-CodeWhale-Webhook-Secret\": redacted_env(name) }),\n        None => json!({}),\n    }\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\"));","sourceCodeStart":471,"sourceCodeEnd":507,"githubUrl":"https://github.com/Hmbown/CodeWhale/blob/73e0f67d83c59909b571efdfc88c4bc28c309cb1/crates/tui/src/fleet/alerts.rs#L471-L507","documentation":"Fleet alert adapters (Slack, webhook, etc.) resolve secrets through a FleetAlertSecretResolver. `required_secret` is a hard requirement: if the resolver returns None for a named secret, the adapter cannot authenticate and the alert send fails with this error.","triggerScenarios":"Calling `send_alert` for an adapter that calls `required_secret(resolver, name)` where the resolver has no value for `name` (e.g. an env var like FLEET_SLACK_TOKEN is unset).","commonSituations":"Secret env var not exported in the deployment environment; secrets file not mounted in the container; secret renamed in code but not in the secret store; dry-run mode passed but secret checks still enforced before send.","solutions":["Set the missing secret in the resolver's backing store (env var, secrets file) using the exact name from the error.","Verify the secret name matches between the adapter config and the secret store (case-sensitive).","Check that the process environment actually receives the secret (CI secrets mapping, container env)."],"exampleFix":"// before\nexport FLEET_SLACK_TOKEN=  # empty\n// after\nexport FLEET_SLACK_TOKEN=xoxb-...","handlingStrategy":"validation","validationCode":"fn ensure_alert_secrets(names: &[&str]) -> Result<()> {\n    for name in names {\n        anyhow::ensure!(\n            std::env::var(name).map(|v| !v.is_empty()).unwrap_or(false),\n            \"missing alert secret {name}\"\n        );\n    }\n    Ok(())\n}","typeGuard":null,"tryCatchPattern":"match send_alert(adapter, &prepared).await {\n    Err(e) if e.to_string().contains(\"secret\") && e.to_string().contains(\"not configured\") => {\n        log::error!(\"cannot send alert, secret missing: {e}\");\n        // queue for retry once secrets are provisioned\n    }\n    other => other?,\n}","preventionTips":["List each adapter's required secrets in its config docs and check them at startup.","Use CI/CD secret mapping tests to confirm env vars reach the process.","Keep secret names centralized so renames stay consistent."],"tags":["fleet","alerts","secrets","configuration"],"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"}