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

Docker runtime requires an absolute workspace path, got: {}

Error message

Docker runtime requires an absolute workspace path, got: {}

What it means

DockerRuntime::workspace_mount_path resolves the configured workspace directory and requires the result to be absolute, because it is used verbatim as the source of a docker bind mount. A relative path cannot be expressed as a mount source, so it is rejected up front inside build_shell_command_inner before any docker command is assembled.

Source

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

pub struct DockerRuntime {
    config: DockerRuntimeConfig,
}

impl DockerRuntime {
    pub fn new(config: DockerRuntimeConfig) -> Self {
        Self { config }
    }

    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| {

View on GitHub (pinned to 88bb9c8533)

Solutions

  1. Set the workspace to an absolute path in the config (e.g. /home/me/zeroclaw-workspace).
  2. If the value comes from a CLI arg or env var, canonicalize it before it reaches the runtime: std::env::current_dir()?.join(p).
  3. Check the error's printed resolved value — it tells you exactly what failed to become absolute.
  4. Guard against empty workspace strings, which also resolve relative.

Example fix

// before
let ws = std::path::Path::new(&cfg.workspace_dir); // "workspace" — relative, docker runtime rejects

// after
let ws = std::env::current_dir()?.join(&cfg.workspace_dir); // absolute, mountable
Defensive patterns

Strategy: validation

Validate before calling

let ws = std::path::Path::new(&workspace_str);
if !ws.is_absolute() {
    let ws = std::env::current_dir()?.join(ws); // make absolute before docker runtime
}
// also cheap sanity: non-empty
assert!(!workspace_str.trim().is_empty());

Try / catch

match docker_runtime.build_shell_command_inner(cmd) {
    Err(e) if e.to_string().contains("absolute workspace path") => {
        // fix the workspace config to an absolute path, then rebuild the runtime
    }
    other => other,
}

Prevention

When it happens

Trigger: runtime.kind = "docker" with a workspace value that is or resolves to a relative path ("work", ".", or an empty string). The check fires when build_shell_command_inner calls workspace_mount_path to construct the mount.

Common situations: Porting a native-runtime config to docker by only flipping runtime.kind; scripts computing the workspace from a relative CLI argument; configs reused across machines where the relative base differs.

Related errors


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