{"record":{"id":"dd033a69b49d7d7a","repo":"zeroclaw-labs/zeroclaw","slug":"auth-secret-requires-a-config-toml-path","errorCode":null,"errorMessage":"auth_secret requires a config.toml path","messagePattern":"auth_secret requires a config\\.toml path","errorType":"validation","errorClass":"anyhow::Error","httpStatus":null,"severity":"error","filePath":"crates/zeroclaw-tools/src/http_request.rs","lineNumber":291,"sourceCode":"        {\n            anyhow::bail!(\n                \"auth_secret must contain only ASCII letters, numbers, underscores, or hyphens\"\n            );\n        }\n        Ok(())\n    }\n\n    fn resolve_auth_secret(&self, secret_name: &str) -> anyhow::Result<String> {\n        Self::validate_secret_name(secret_name)?;\n        self.reload_auth_secret(secret_name)\n    }\n\n    fn reload_auth_secret(&self, secret_name: &str) -> anyhow::Result<String> {\n        let config_path = self.config_path.as_ref().ok_or_else(|| {\n            anyhow::Error::msg(\"auth_secret requires runtime config reload support\")\n        })?;\n        if config_path.as_os_str().is_empty() {\n            anyhow::bail!(\"auth_secret requires a config.toml path\");\n        }\n\n        let contents = std::fs::read_to_string(config_path).map_err(|e| {\n            anyhow::Error::msg(format!(\n                \"Failed to read config file {} for auth_secret '{secret_name}': {e}\",\n                config_path.display()\n            ))\n        })?;\n        let config: zeroclaw_config::schema::Config = toml::from_str(&contents).map_err(|e| {\n            anyhow::Error::msg(format!(\n                \"Failed to parse config file {} for auth_secret '{secret_name}': {e}\",\n                config_path.display()\n            ))\n        })?;\n\n        let raw_secret = config\n            .http_request\n            .secrets","sourceCodeStart":273,"sourceCodeEnd":309,"githubUrl":"https://github.com/zeroclaw-labs/zeroclaw/blob/88bb9c8533fc57ed7a03e36ca7c9ed2bf8336dcc/crates/zeroclaw-tools/src/http_request.rs#L273-L309","documentation":"Thrown by HttpRequestTool::reload_auth_secret (crates/zeroclaw-tools/src/http_request.rs:291) when the tool was built with a config path that is Some but empty. auth_secret values are resolved by re-reading config.toml at request time (so secret rotations do not need a restart), which is impossible without a real path. A distinct sibling error (\"auth_secret requires runtime config reload support\") fires when the path is None, i.e. the tool was built with HttpRequestTool::new instead of new_with_config.","triggerScenarios":"Constructing via HttpRequestTool::new_with_config with PathBuf::from(\"\"); runtime wiring that reads a CONFIG_PATH env var which is unset, producing an empty path; passing a config_path that was cleared during initialization; calling resolve_auth_secret on such a tool. The None case (HttpRequestTool::new) raises the sibling error instead.","commonSituations":"Embedding the tool in a custom host that forgot to locate its config; config path resolution order changing between versions; test harnesses constructing the tool without a config file and then exercising auth_secret.","solutions":["Build the tool with HttpRequestTool::new_with_config and the absolute path of the live config.toml.","If you run the standard runtime, make sure the runtime's config discovery (config path env/flag) resolves to a non-empty path.","If you never use auth_secret, you can ignore this; literal Authorization headers work without a config path."],"exampleFix":"// before\nlet tool = HttpRequestTool::new_with_config(sec, domains, 1_000_000, 30, false, vec![], vec![], PathBuf::from(\"\"), false);\n\n// after\nlet tool = HttpRequestTool::new_with_config(sec, domains, 1_000_000, 30, false, vec![], vec![], config_dir.join(\"config.toml\"), secrets_encrypt);","handlingStrategy":"validation","validationCode":"fn auth_secret_support_available(config_path: &Option<std::path::PathBuf>) -> bool {\n    config_path.as_ref().is_some_and(|p| !p.as_os_str().is_empty())\n}\n// check before enabling UI/flows that use auth_secret","typeGuard":null,"tryCatchPattern":"let result = tool.execute(args).await?;\nif let Some(err) = &result.error {\n    if err.contains(\"requires a config.toml path\") || err.contains(\"runtime config reload support\") {\n        // host misconfiguration: rebuild tool with the real config path; do not retry\n    }\n}","preventionTips":["Always construct the tool via new_with_config with a resolved, non-empty absolute config path.","Fail startup if the config path env var resolves to empty when auth_secret features are enabled.","Smoke-test one auth_secret resolution at startup to catch wiring errors early."],"tags":["http","auth","secrets","configuration","zeroclaw"],"backgroundTag":"missing-config-path","analyzedSha":"88bb9c8533fc57ed7a03e36ca7c9ed2bf8336dcc","analyzedAt":"2026-08-23T01:07:41.857Z","schemaVersion":2},"datasetVersion":"2026-08-23T08:06:27.607Z"}