zeroclaw-labs/zeroclaw · error · anyhow::Error

environment-backed auth_secret references an empty environme

Error message

environment-backed auth_secret references an empty environment variable name

What it means

Thrown by env_secret_reference (crates/zeroclaw-tools/src/http_request.rs:451) when a secret's config value is exactly "${}" — the environment-reference syntax with an empty variable name inside the braces. The parser strips ${ and } and then requires a non-empty identifier; an empty name can never be looked up, so it is rejected as a configuration typo rather than treated as a literal value.

Source

Thrown at crates/zeroclaw-tools/src/http_request.rs:451

    })?;
    if value.is_empty() {
        anyhow::bail!(
            "auth_secret '{secret_name}' references environment variable '{env_name}', but it is empty"
        );
    }
    Ok(Some(value))
}

fn env_secret_reference(raw_secret: &str) -> anyhow::Result<Option<&str>> {
    let Some(inner) = raw_secret
        .strip_prefix("${")
        .and_then(|value| value.strip_suffix('}'))
    else {
        return Ok(None);
    };

    if inner.is_empty() {
        anyhow::bail!(
            "environment-backed auth_secret references an empty environment variable name"
        );
    }
    if !inner.chars().all(|c| c.is_ascii_alphanumeric() || c == '_') {
        anyhow::bail!(
            "environment-backed auth_secret '{inner}' must contain only ASCII letters, numbers, or underscores"
        );
    }
    Ok(Some(inner))
}

#[async_trait]
impl Tool for HttpRequestTool {
    fn name(&self) -> &str {
        "http_request"
    }

    fn description(&self) -> &str {

View on GitHub (pinned to 88bb9c8533)

Solutions

  1. Fill in a real variable name: api_token = "${API_TOKEN}".
  2. If you did not intend an env reference, drop the braces entirely and store the literal or encrypted value.
  3. Validate rendered config templates for ${} placeholders before deployment.

Example fix

# before
[http_request.secrets]
api_token = "${}"

# after
[http_request.secrets]
api_token = "${API_TOKEN}"
Defensive patterns

Strategy: validation

Validate before calling

fn env_reference_well_formed(raw: &str) -> bool {
    match raw.strip_prefix("${").and_then(|v| v.strip_suffix('}')) {
        Some(inner) => !inner.is_empty(),
        None => true, // literal or encrypted value, no reference to check
    }
}

Try / catch

let result = tool.execute(args).await?;
if let Some(err) = &result.error {
    if err.contains("empty environment variable name") {
        // config typo: fill in the variable name inside ${...}
    }
}

Prevention

When it happens

Trigger: [http_request.secrets] api_token = "${}" in config.toml; templating that interpolates an unset variable name into the braces, producing "${}"; hand-editing that deleted the variable name; encrypting a placeholder "${}" value. Literal values that merely contain $ or braces but do not match the exact ${...} shape are treated as literals and do not trigger this.

Common situations: Config templates with a missing variable after rendering; secrets created by scripts whose variable-name argument was empty; copy-paste from docs leaving the placeholder unfilled.

Related errors


AI-assisted analysis of zeroclaw-labs/zeroclaw@88bb9c8533 (2026-08-23). Data as JSON: /api/errors/d3a5ba9e7f379290. Report an issue: GitHub.