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

runtime.wasm.tools_dir cannot be empty

Error message

runtime.wasm.tools_dir cannot be empty

What it means

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.

Source

Thrown at crates/zeroclaw-runtime/src/platform/wasm.rs:77

    /// Check if the WASM runtime feature is available in this build.
    pub fn is_available() -> bool {
        cfg!(feature = "runtime-wasm")
    }

    /// Validate the WASM config for common misconfigurations.
    pub fn validate_config(&self) -> Result<()> {
        if self.config.memory_limit_mb == 0 {
            bail!("runtime.wasm.memory_limit_mb must be > 0");
        }
        if self.config.memory_limit_mb > 4096 {
            bail!(
                "runtime.wasm.memory_limit_mb of {} exceeds the 4 GB safety limit for 32-bit WASM",
                self.config.memory_limit_mb
            );
        }
        if self.config.tools_dir.is_empty() {
            bail!("runtime.wasm.tools_dir cannot be empty");
        }
        // Verify tools directory doesn't escape workspace
        if self.config.tools_dir.contains("..") {
            bail!("runtime.wasm.tools_dir must not contain '..' path traversal");
        }
        Ok(())
    }

    /// Resolve the absolute path to the WASM tools directory.
    pub fn tools_dir(&self, workspace_dir: &Path) -> PathBuf {
        workspace_dir.join(&self.config.tools_dir)
    }

    /// Build capabilities from config defaults.
    pub fn default_capabilities(&self) -> WasmCapabilities {
        WasmCapabilities {
            read_workspace: self.config.allow_workspace_read,
            write_workspace: self.config.allow_workspace_write,

View on GitHub (pinned to 88bb9c8533)

Solutions

  1. Set tools_dir to a directory under the workspace, e.g. tools_dir = "tools/wasm", and create it
  2. If you do not want WASM tooling, switch the runtime kind to native instead of blanking the field
  3. Check for typos/renames in the [runtime.wasm] table
  4. Run validate_config() at startup to catch this before modules are requested

Example fix

# before
[runtime.wasm]
memory_limit_mb = 256

# after
[runtime.wasm]
memory_limit_mb = 256
tools_dir = "tools/wasm"
Defensive patterns

Strategy: validation

Validate before calling

if cfg.tools_dir.is_empty() {
    // reject at config load: tools_dir is required for the wasm runtime
    return Err("runtime.wasm.tools_dir cannot be empty".into());
}

Try / catch

if let Err(e) = platform.validate_config() {
    // config error surfaced at boot; fix the [runtime.wasm] table and restart
}

Prevention

When it happens

Trigger: 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.

Common situations: 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.

Understand the failure class

Background: Config validation failed: what "invalid value for {key}" and settings-rejection errors mean across 19 open-source libraries — this error's family across 19 libraries.

Related errors


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