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

Refusing to mount filesystem root (/) into docker runtime

Error message

Refusing to mount filesystem root (/) into docker runtime

What it means

A deliberate safety guard in workspace_mount_path: if the resolved workspace is exactly /, the docker runtime refuses to build the command rather than bind-mounting the host's entire filesystem into the container. It runs before the allowed_workspace_roots check, so no allowlist configuration can override it.

Source

Thrown at crates/zeroclaw-config/src/platform/docker.rs:53

    }

    fn workspace_mount_path(&self, workspace_dir: &Path) -> Result<PathBuf> {
        let resolved = workspace_dir.canonicalize().map_err(|source| {
            DockerWorkspaceMountError::WorkspacePath {
                path: workspace_dir.display().to_string(),
                source,
            }
        })?;

        if !resolved.is_absolute() {
            anyhow::bail!(
                "Docker runtime requires an absolute workspace path, got: {}",
                resolved.display()
            );
        }

        if resolved == Path::new("/") {
            anyhow::bail!("Refusing to mount filesystem root (/) into docker runtime");
        }

        if self.config.allowed_workspace_roots.is_empty() {
            return Ok(resolved);
        }

        let allowed_roots = self
            .config
            .allowed_workspace_roots
            .iter()
            .map(|root| {
                Path::new(root).canonicalize().map_err(|source| {
                    DockerWorkspaceMountError::AllowedRoot {
                        path: root.clone(),
                        source,
                    }
                })
            })

View on GitHub (pinned to 88bb9c8533)

Solutions

  1. Point the workspace at a real subdirectory such as /workspace or /home/me/work.
  2. Inspect the symlink chain with readlink -f <path> and fix the link that escapes to /.
  3. If the process cwd is /, run from the project directory or pass an absolute subpath.

Example fix

# before
workspace_dir = "/"   # refused: mounting filesystem root

# after
workspace_dir = "/home/me/zeroclaw/workspace"
Defensive patterns

Strategy: validation

Validate before calling

let resolved = std::fs::canonicalize(&workspace_dir)?;
if resolved == std::path::Path::new("/") {
    return Err(anyhow::anyhow!("workspace resolves to /; pick a subdirectory"));
}

Try / catch

match docker_runtime.build_shell_command_inner(cmd) {
    Err(e) if e.to_string().contains("filesystem root") => {
        // workspace or a symlink escapes to /; fix the path or symlink chain
    }
    other => other,
}

Prevention

When it happens

Trigger: workspace_dir resolves to / — set explicitly, produced by resolving "." while the process cwd is /, or reached through a symlink chain whose canonicalized target is the filesystem root. Fires inside build_shell_command_inner via workspace_mount_path.

Common situations: Typo'd workspace_dir = "/"; CI or container environments where the workspace symlink points at /; running zeroclaw from the root directory with a relative workspace.

Related errors


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