Hmbown/CodeWhale · error

Fleet alert secret is not configured

Error message

Fleet alert secret {name} is not configured

What it means

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.

Solutions

  1. Set the missing secret in the resolver's backing store (env var, secrets file) using the exact name from the error.
  2. Verify the secret name matches between the adapter config and the secret store (case-sensitive).
  3. Check that the process environment actually receives the secret (CI secrets mapping, container env).

Example fix

// before
export FLEET_SLACK_TOKEN=  # empty
// after
export FLEET_SLACK_TOKEN=xoxb-...
Defensive patterns

Strategy: validation

Validate before calling

fn ensure_alert_secrets(names: &[&str]) -> Result<()> {
    for name in names {
        anyhow::ensure!(
            std::env::var(name).map(|v| !v.is_empty()).unwrap_or(false),
            "missing alert secret {name}"
        );
    }
    Ok(())
}

Try / catch

match send_alert(adapter, &prepared).await {
    Err(e) if e.to_string().contains("secret") && e.to_string().contains("not configured") => {
        log::error!("cannot send alert, secret missing: {e}");
        // queue for retry once secrets are provisioned
    }
    other => other?,
}

Prevention

When it happens

Trigger: 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).

Common situations: 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.

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


AI-assisted analysis of Hmbown/CodeWhale@73e0f67d83 (2026-09-22). Data as JSON: /api/errors/f64d93b1b4341422. Report an issue: GitHub.

Appendix: 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 73e0f67d83)