{"record":{"id":"cebceba663e34928","repo":"zeroclaw-labs/zeroclaw","slug":"runtime-wasm-tools-dir-cannot-be-empty","errorCode":null,"errorMessage":"runtime.wasm.tools_dir cannot be empty","messagePattern":"runtime\\.wasm\\.tools_dir cannot be empty","errorType":"validation","errorClass":"anyhow::Error","httpStatus":null,"severity":"error","filePath":"crates/zeroclaw-runtime/src/platform/wasm.rs","lineNumber":77,"sourceCode":"\n    /// Check if the WASM runtime feature is available in this build.\n    pub fn is_available() -> bool {\n        cfg!(feature = \"runtime-wasm\")\n    }\n\n    /// Validate the WASM config for common misconfigurations.\n    pub fn validate_config(&self) -> Result<()> {\n        if self.config.memory_limit_mb == 0 {\n            bail!(\"runtime.wasm.memory_limit_mb must be > 0\");\n        }\n        if self.config.memory_limit_mb > 4096 {\n            bail!(\n                \"runtime.wasm.memory_limit_mb of {} exceeds the 4 GB safety limit for 32-bit WASM\",\n                self.config.memory_limit_mb\n            );\n        }\n        if self.config.tools_dir.is_empty() {\n            bail!(\"runtime.wasm.tools_dir cannot be empty\");\n        }\n        // Verify tools directory doesn't escape workspace\n        if self.config.tools_dir.contains(\"..\") {\n            bail!(\"runtime.wasm.tools_dir must not contain '..' path traversal\");\n        }\n        Ok(())\n    }\n\n    /// Resolve the absolute path to the WASM tools directory.\n    pub fn tools_dir(&self, workspace_dir: &Path) -> PathBuf {\n        workspace_dir.join(&self.config.tools_dir)\n    }\n\n    /// Build capabilities from config defaults.\n    pub fn default_capabilities(&self) -> WasmCapabilities {\n        WasmCapabilities {\n            read_workspace: self.config.allow_workspace_read,\n            write_workspace: self.config.allow_workspace_write,","sourceCodeStart":59,"sourceCodeEnd":95,"githubUrl":"https://github.com/zeroclaw-labs/zeroclaw/blob/88bb9c8533fc57ed7a03e36ca7c9ed2bf8336dcc/crates/zeroclaw-runtime/src/platform/wasm.rs#L59-L95","documentation":"Third WASM config guard in validate_config: tools_dir (the directory, relative to the workspace, where .wasm tool modules are looked up) must be a non-empty string. An empty value would make every module lookup resolve against the workspace root itself (or an meaningless path), so it is rejected during validation before any module executes.","triggerScenarios":"Omitting tools_dir from [runtime.wasm] in a config type where it defaults to empty; explicitly clearing it (tools_dir = \"\") intending to disable tool loading; TOML typo producing a different key so the real one stays unset.","commonSituations":"Minimal hand-written configs that only set memory_limit_mb; config generators that conditionally emit the key and skip it when a variable is empty; refactors that renamed the key and left deployments without it.","solutions":["Set tools_dir to a directory under the workspace, e.g. tools_dir = \"tools/wasm\", and create it","If you do not want WASM tooling, switch the runtime kind to native instead of blanking the field","Check for typos/renames in the [runtime.wasm] table","Run validate_config() at startup to catch this before modules are requested"],"exampleFix":"# before\n[runtime.wasm]\nmemory_limit_mb = 256\n\n# after\n[runtime.wasm]\nmemory_limit_mb = 256\ntools_dir = \"tools/wasm\"","handlingStrategy":"validation","validationCode":"if cfg.tools_dir.is_empty() {\n    // reject at config load: tools_dir is required for the wasm runtime\n    return Err(\"runtime.wasm.tools_dir cannot be empty\".into());\n}","typeGuard":null,"tryCatchPattern":"if let Err(e) = platform.validate_config() {\n    // config error surfaced at boot; fix the [runtime.wasm] table and restart\n}","preventionTips":["Always emit both memory_limit_mb and tools_dir in generated [runtime.wasm] blocks","Prefer disabling wasm via runtime.kind than by blanking wasm fields","Schema-validate user-supplied config before it reaches the platform"],"tags":["rust","zeroclaw","wasm","config","validation","paths"],"backgroundTag":"config-validation-failed","analyzedSha":"88bb9c8533fc57ed7a03e36ca7c9ed2bf8336dcc","analyzedAt":"2026-08-23T01:07:41.857Z","schemaVersion":2},"datasetVersion":"2026-08-23T08:06:27.607Z"}