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
- Fill in a real variable name: api_token = "${API_TOKEN}".
- If you did not intend an env reference, drop the braces entirely and store the literal or encrypted value.
- 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
- Lint config.toml for the literal "${}" placeholder after template rendering.
- Never commit placeholder secrets; fail CI on unresolved template variables.
- Distinguish intentional literals from references: only exact ${...} values are parsed as references.
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
- auth_secret requires a config.toml path
- auth_secret cannot be empty
- auth_secret must be 64 characters or fewer
- auth_secret must contain only ASCII letters, numbers, unders
- auth_secret '{secret_name}' is empty after decryption
AI-assisted analysis of zeroclaw-labs/zeroclaw@88bb9c8533 (2026-08-23).
Data as JSON: /api/errors/d3a5ba9e7f379290.
Report an issue: GitHub.