{"record":{"id":"5ac3e5784ed03dba","repo":"zeroclaw-labs/zeroclaw","slug":"missing-worktree-path-parameter-for-worktree-add","errorCode":null,"errorMessage":"Missing 'worktree_path' parameter for worktree add","messagePattern":"Missing 'worktree_path' parameter for worktree add","errorType":"validation","errorClass":"anyhow::Error","httpStatus":null,"severity":"error","filePath":"crates/zeroclaw-tools/src/git_operations.rs","lineNumber":782,"sourceCode":"\n        match subcommand {\n            \"list\" => {\n                let output = self\n                    .run_git_command(&[\"worktree\", \"list\", \"--porcelain\"], working_dir)\n                    .await?;\n                let parsed = self.parse_worktree_list(&output);\n                Ok(ToolResult {\n                    success: true,\n                    output: serde_json::to_string_pretty(&parsed)\n                        .unwrap_or_default()\n                        .into(),\n                    error: None,\n                })\n            }\n            \"add\" => {\n                let worktree_path = match args.get(\"worktree_path\").and_then(|v| v.as_str()) {\n                    Some(p) => p,\n                    None => anyhow::bail!(\"Missing 'worktree_path' parameter for worktree add\"),\n                };\n                self.sanitize_git_args(worktree_path)?;\n                let worktree_path = self.ensure_worktree_add_target_allowed(worktree_path)?;\n                let worktree_path = worktree_path.to_str().ok_or_else(|| {\n                    ::zeroclaw_log::record!(\n                        WARN,\n                        ::zeroclaw_log::Event::new(module_path!(), ::zeroclaw_log::Action::Reject)\n                            .with_outcome(::zeroclaw_log::EventOutcome::Failure),\n                        \"git_operations: worktree path not valid UTF-8\"\n                    );\n                    anyhow::Error::msg(\"Worktree path must be valid UTF-8 for git execution\")\n                })?;\n\n                let branch = args\n                    .get(\"branch\")\n                    .and_then(|v| v.as_str())\n                    .unwrap_or_default();\n                // git worktree add <path> [<branch>]","sourceCodeStart":764,"sourceCodeEnd":800,"githubUrl":"https://github.com/zeroclaw-labs/zeroclaw/blob/88bb9c8533fc57ed7a03e36ca7c9ed2bf8336dcc/crates/zeroclaw-tools/src/git_operations.rs#L764-L800","documentation":"Inside git_worktree, the \"add\" branch requires a 'worktree_path' string in the args; if it is missing or not a string, the tool bails with 'Missing 'worktree_path' parameter for worktree add'. The path is subsequently sanitized and passed through ensure_worktree_add_target_allowed, which constrains where a new worktree may be created — but the bail here happens first, purely on argument shape. It fires only when subcommand == \"add\".","triggerScenarios":"Calling the worktree tool with {\"subcommand\": \"add\"} and no 'worktree_path' key; passing a non-string value like {\"worktree_path\": 42} or null; misspelling the key as \"path\" or \"worktree\". Passing a blank string does NOT hit this error (it is a string) and instead flows into sanitization/target checks.","commonSituations":"A caller assumes the tool derives the worktree path from the branch name; an agent emits only the branch argument; a script builds args conditionally and the path variable was unset; key-name drift between the tool schema and the caller after a version change.","solutions":["Include an explicit absolute or repo-relative path string: {\"subcommand\": \"add\", \"worktree_path\": \"/tmp/zc-feature\"}.","Verify the key name is exactly 'worktree_path' (snake_case).","Validate that the path variable is set before constructing args; fail fast in the caller with your own clearer message.","Check that the target directory location is allowed by the tool's worktree-add target policy, since that check runs right after this one."],"exampleFix":"// before\nlet args = serde_json::json!({ \"subcommand\": \"add\" });\n// tool bails: Missing 'worktree_path' parameter for worktree add\n\n// after\nlet args = serde_json::json!({ \"subcommand\": \"add\", \"worktree_path\": \"/tmp/zc-feature\" });","handlingStrategy":"validation","validationCode":"fn build_worktree_add(path: &str) -> Option<serde_json::Value> {\n    (!path.is_empty()).then(|| serde_json::json!({ \"subcommand\": \"add\", \"worktree_path\": path }))\n}","typeGuard":"fn is_valid_worktree_add_args(args: &serde_json::Value) -> bool {\n    args.get(\"subcommand\").and_then(|v| v.as_str()) == Some(\"add\")\n        && args.get(\"worktree_path\").and_then(|v| v.as_str()).is_some()\n}","tryCatchPattern":"match tool_result {\n    Err(e) if e.to_string().contains(\"for worktree add\") => {\n        // the path never made it into args; rebuild args with an explicit path\n    }\n    other => other,\n}","preventionTips":["Derive worktree paths from one canonical source (e.g. a workspace metadata file), not ad-hoc strings.","Reject empty path strings in the caller — the tool's missing-check only catches absent/non-string, not blank.","Keep add/remove call sites symmetric so both always carry 'worktree_path'."],"tags":["git","worktree","missing-parameter","validation","zeroclaw-tools"],"backgroundTag":"missing-required-parameter","analyzedSha":"88bb9c8533fc57ed7a03e36ca7c9ed2bf8336dcc","analyzedAt":"2026-08-23T01:07:41.857Z","schemaVersion":2},"datasetVersion":"2026-08-23T08:06:27.607Z"}