Hmbown/CodeWhale · error

fleet alert secret {name} is not configured

Error message

fleet alert secret {name} is not configured

What it means

Alert adapters resolve secrets by name through a `FleetAlertSecretResolver`; the default `FleetEnvSecretResolver` reads `std::env::var(name)` and treats empty strings as unset (fleet/alerts.rs:86-90). `required_secret` errors when resolve returns None — the named secret (e.g. a webhook signing token) simply is not configured in the dispatching process.

Source

Thrown at crates/tui/src/fleet/alerts.rs:489

        FleetAlertEventClass::VerifierFailed => "verifier_failed",
        FleetAlertEventClass::RunCompleted => "run_completed",
    }
}

fn redacted_secret_header(secret_env: Option<&str>) -> Value {
    match secret_env {
        Some(name) => json!({ "X-CodeWhale-Webhook-Secret": redacted_env(name) }),
        None => json!({}),
    }
}

fn required_secret<R>(resolver: &R, name: &str) -> Result<String>
where
    R: FleetAlertSecretResolver,
{
    resolver
        .resolve(name)
        .ok_or_else(|| anyhow!("fleet alert secret {name} is not configured"))
}

fn required_https_url<R>(resolver: &R, name: &str) -> Result<String>
where
    R: FleetAlertSecretResolver,
{
    let url = resolver
        .resolve(name)
        .ok_or_else(|| anyhow!("fleet alert URL {name} is not configured"))?;
    validate_https_alert_url(name, &url)?;
    Ok(url)
}

fn validate_https_alert_url(name: &str, url: &str) -> Result<()> {
    let parsed = reqwest::Url::parse(url)
        .with_context(|| format!("fleet alert URL from {name} is not a valid URL"))?;
    if parsed.scheme() != "https" {
        return Err(anyhow!("fleet alert URL from {name} must use https"));

View on GitHub (pinned to 8880682c63)

Solutions

  1. Export the named variable with a non-empty value in the environment that dispatches alerts
  2. Fix the secret name in adapter config to match the provisioned variable
  3. Smoke-test resolution (present and non-empty) before enabling live dispatch; iterate with dry_run

Example fix

# before: FLEET_WEBHOOK_SECRET unset where the dispatcher runs
# after (provision in that environment)
export FLEET_WEBHOOK_SECRET='...'
systemctl restart codewhale-fleet
Defensive patterns

Strategy: validation

Validate before calling

fn secret_ready(name: &str) -> bool {
    std::env::var(name).map(|v| !v.is_empty()).unwrap_or(false)
}
anyhow::ensure!(
    secret_ready(&adapter.secret_env),
    "set {} before dispatching alerts",
    adapter.secret_env
);

Type guard

fn secret_ready(name: &str) -> bool {
    std::env::var(name).map(|v| !v.is_empty()).unwrap_or(false)
}

Prevention

When it happens

Trigger: The env var named by adapter config is unset or empty where the dispatcher runs; the secret name in config is misspelled; the secret exists in a dev shell but not in the service or CI environment.

Common situations: Deploying without provisioning alert secrets; CI lacking env vars; name drift between adapter config and provisioning.

Related errors


AI-assisted analysis of Hmbown/CodeWhale@8880682c63 (2026-08-16). Data as JSON: /api/errors/d354ff7198023a33. Report an issue: GitHub.