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

auth_secret cannot be empty

Error message

auth_secret cannot be empty

What it means

Thrown by HttpRequestTool::validate_secret_name (crates/zeroclaw-tools/src/http_request.rs:265) when the auth_secret argument is an empty string. auth_secret must name an entry in [http_request.secrets] of config.toml; an empty name can never match one. Passing no auth_secret at all is fine (the parameter is optional), so this error specifically means the field was present but blank.

Source

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

        if let Some(obj) = headers.as_object() {
            for (key, value) in obj {
                let Some(str_val) = value.as_str() else {
                    anyhow::bail!("Header '{key}' value must be a string, got: {}", value);
                };
                let header_name = HeaderName::from_str(key)
                    .map_err(|e| anyhow::Error::msg(format!("Invalid header name '{key}': {e}")))?;
                let header_value = HeaderValue::from_str(str_val).map_err(|e| {
                    anyhow::Error::msg(format!("Invalid value for header '{key}': {e}"))
                })?;
                result.insert(header_name, header_value);
            }
        }
        Ok(result)
    }

    fn validate_secret_name(secret_name: &str) -> anyhow::Result<()> {
        if secret_name.is_empty() {
            anyhow::bail!("auth_secret cannot be empty");
        }
        if secret_name.len() > 64 {
            anyhow::bail!("auth_secret must be 64 characters or fewer");
        }
        if !secret_name
            .chars()
            .all(|c| c.is_ascii_alphanumeric() || c == '_' || c == '-')
        {
            anyhow::bail!(
                "auth_secret must contain only ASCII letters, numbers, underscores, or hyphens"
            );
        }
        Ok(())
    }

    fn resolve_auth_secret(&self, secret_name: &str) -> anyhow::Result<String> {
        Self::validate_secret_name(secret_name)?;
        self.reload_auth_secret(secret_name)

View on GitHub (pinned to 88bb9c8533)

Solutions

  1. Omit the auth_secret field entirely when no Authorization header is needed.
  2. If auth is required, pass the real key name defined under [http_request.secrets], e.g. "api_token".
  3. Guard in the caller: only include auth_secret when the variable is non-empty.

Example fix

// before
let args = json!({"url": u, "auth_secret": secret_name_var}); // var is ""

// after
let mut args = json!({"url": u});
if !secret_name_var.is_empty() {
    args["auth_secret"] = json!(secret_name_var);
}
Defensive patterns

Strategy: validation

Validate before calling

fn auth_secret_arg(name: Option<&str>) -> Option<&str> {
    name.filter(|n| !n.is_empty())
}

Type guard

fn is_usable_secret_name(name: &str) -> bool {
    !name.is_empty()
}

Try / catch

let result = tool.execute(args).await?;
if let Some(err) = &result.error {
    if err.contains("auth_secret cannot be empty") {
        // drop the empty field and send an unauthenticated request if acceptable
    }
}

Prevention

When it happens

Trigger: args = {"url": u, "auth_secret": ""}; templates that interpolate an optional secret name variable which resolved to empty; JSON built with a default empty string instead of omitting the key; note auth_secret: null produces a different error ("'auth_secret' must be a string").

Common situations: Optional-auth code paths that always include the key; LLM tool calls that emit an empty auth_secret when unsure; config-driven header injection where the secret name variable was never set.

Related errors


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