{"record":{"id":"f9e6d9ad38fab69c","repo":"zeroclaw-labs/zeroclaw","slug":"docker-runtime-requires-an-absolute-workspace-path","errorCode":null,"errorMessage":"Docker runtime requires an absolute workspace path, got: {}","messagePattern":"Docker runtime requires an absolute workspace path, got: (.+?)","errorType":"validation","errorClass":"anyhow::Error","httpStatus":null,"severity":"error","filePath":"crates/zeroclaw-config/src/platform/docker.rs","lineNumber":46,"sourceCode":"pub struct DockerRuntime {\n    config: DockerRuntimeConfig,\n}\n\nimpl DockerRuntime {\n    pub fn new(config: DockerRuntimeConfig) -> Self {\n        Self { config }\n    }\n\n    fn workspace_mount_path(&self, workspace_dir: &Path) -> Result<PathBuf> {\n        let resolved = workspace_dir.canonicalize().map_err(|source| {\n            DockerWorkspaceMountError::WorkspacePath {\n                path: workspace_dir.display().to_string(),\n                source,\n            }\n        })?;\n\n        if !resolved.is_absolute() {\n            anyhow::bail!(\n                \"Docker runtime requires an absolute workspace path, got: {}\",\n                resolved.display()\n            );\n        }\n\n        if resolved == Path::new(\"/\") {\n            anyhow::bail!(\"Refusing to mount filesystem root (/) into docker runtime\");\n        }\n\n        if self.config.allowed_workspace_roots.is_empty() {\n            return Ok(resolved);\n        }\n\n        let allowed_roots = self\n            .config\n            .allowed_workspace_roots\n            .iter()\n            .map(|root| {","sourceCodeStart":28,"sourceCodeEnd":64,"githubUrl":"https://github.com/zeroclaw-labs/zeroclaw/blob/88bb9c8533fc57ed7a03e36ca7c9ed2bf8336dcc/crates/zeroclaw-config/src/platform/docker.rs#L28-L64","documentation":"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.","triggerScenarios":"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.","commonSituations":"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.","solutions":["Set the workspace to an absolute path in the config (e.g. /home/me/zeroclaw-workspace).","If the value comes from a CLI arg or env var, canonicalize it before it reaches the runtime: std::env::current_dir()?.join(p).","Check the error's printed resolved value — it tells you exactly what failed to become absolute.","Guard against empty workspace strings, which also resolve relative."],"exampleFix":"// before\nlet ws = std::path::Path::new(&cfg.workspace_dir); // \"workspace\" — relative, docker runtime rejects\n\n// after\nlet ws = std::env::current_dir()?.join(&cfg.workspace_dir); // absolute, mountable","handlingStrategy":"validation","validationCode":"let ws = std::path::Path::new(&workspace_str);\nif !ws.is_absolute() {\n    let ws = std::env::current_dir()?.join(ws); // make absolute before docker runtime\n}\n// also cheap sanity: non-empty\nassert!(!workspace_str.trim().is_empty());","typeGuard":null,"tryCatchPattern":"match docker_runtime.build_shell_command_inner(cmd) {\n    Err(e) if e.to_string().contains(\"absolute workspace path\") => {\n        // fix the workspace config to an absolute path, then rebuild the runtime\n    }\n    other => other,\n}","preventionTips":["Always store absolute workspace paths in configs intended for the docker runtime.","Canonicalize CLI/env-derived workspace values before they reach runtime construction.","Test the docker runtime config once after any workspace path change."],"tags":["docker","workspace","filesystem","path"],"backgroundTag":"docker-mount-path-invalid","analyzedSha":"88bb9c8533fc57ed7a03e36ca7c9ed2bf8336dcc","analyzedAt":"2026-08-23T01:07:41.857Z","schemaVersion":2},"datasetVersion":"2026-08-23T08:06:27.607Z"}