{"record":{"id":"bef5f0b684808f96","repo":"zeroclaw-labs/zeroclaw","slug":"docker-runtime-environment-passthrough-key-must-be","errorCode":null,"errorMessage":"Docker runtime environment passthrough key must be a variable name","messagePattern":"Docker runtime environment passthrough key must be a variable name","errorType":"validation","errorClass":"anyhow::Error","httpStatus":null,"severity":"error","filePath":"crates/zeroclaw-config/src/platform/docker.rs","lineNumber":150,"sourceCode":"                .arg(\"/workspace\");\n        }\n\n        process\n            .arg(self.config.image.trim())\n            .arg(\"sh\")\n            .arg(\"-c\")\n            .arg(command);\n\n        Ok(process)\n    }\n}\n\nfn docker_env_key(key: &OsStr) -> Result<&str> {\n    let key = key\n        .to_str()\n        .context(\"Docker runtime environment passthrough key must be valid UTF-8\")?;\n    if key.is_empty() || key.contains('=') {\n        anyhow::bail!(\"Docker runtime environment passthrough key must be a variable name\");\n    }\n    Ok(key)\n}\n\nimpl RuntimeAdapter for DockerRuntime {\n    fn name(&self) -> &str {\n        \"docker\"\n    }\n\n    fn has_filesystem_access(&self) -> bool {\n        self.config.mount_workspace\n    }\n\n    fn storage_path(&self) -> PathBuf {\n        if self.config.mount_workspace {\n            PathBuf::from(\"/workspace/.zeroclaw\")\n        } else {\n            PathBuf::from(\"/tmp/.zeroclaw\")","sourceCodeStart":132,"sourceCodeEnd":168,"githubUrl":"https://github.com/zeroclaw-labs/zeroclaw/blob/88bb9c8533fc57ed7a03e36ca7c9ed2bf8336dcc/crates/zeroclaw-config/src/platform/docker.rs#L132-L168","documentation":"docker_env_key validates each key from the docker runtime's environment passthrough list. Entries must be plain variable names: an empty key or one containing '=' (a KEY=VALUE pair) is rejected. The list selects which existing environment variables to forward into the container; it does not set values.","triggerScenarios":"The docker runtime env passthrough configuration containing an entry like \"HTTP_PROXY=http://proxy:7890\" or \"\" when build_shell_command_inner iterates the passthrough keys via docker_env_key.","commonSituations":"Copy-pasting KEY=VALUE lines from docker -e flags or .env files into the passthrough list; programmatic lists built by splitting on commas that leave an empty trailing entry.","solutions":["Keep only variable names in the list: [\"HTTP_PROXY\", \"HTTPS_PROXY\"].","Set the actual values in the environment zeroclaw runs in; passthrough forwards them into the container.","If the list is generated from a KEY=VALUE source, split on '=' and keep only the name part, filtering empties."],"exampleFix":"# before\nenv_passthrough = [\"HTTP_PROXY=http://proxy:8080\"]\n\n# after\nenv_passthrough = [\"HTTP_PROXY\"]   # value comes from the parent environment","handlingStrategy":"validation","validationCode":"for key in &env_passthrough_list {\n    if key.is_empty() || key.contains('=') {\n        return Err(anyhow::anyhow!(\"env passthrough entries must be names, got {key:?}\"));\n    }\n}","typeGuard":"fn is_env_var_name(key: &str) -> bool {\n    !key.is_empty() && !key.contains('=')\n}","tryCatchPattern":"match docker_runtime.build_shell_command_inner(cmd) {\n    Err(e) if e.to_string().contains(\"must be a variable name\") => {\n        // strip '=value' parts from the passthrough list and retry\n    }\n    other => other,\n}","preventionTips":["Keep the passthrough list name-only; set values in the parent environment.","Do not paste docker -e KEY=VALUE lines or .env contents into it.","Filter empties when building the list programmatically."],"tags":["docker","environment","env-vars","validation"],"backgroundTag":"env-var-passthrough-invalid","analyzedSha":"88bb9c8533fc57ed7a03e36ca7c9ed2bf8336dcc","analyzedAt":"2026-08-23T01:07:41.857Z","schemaVersion":2},"datasetVersion":"2026-08-23T08:06:27.607Z"}