{"record":{"id":"6459a8ec7e8788f3","repo":"zeroclaw-labs/zeroclaw","slug":"unknown-worktree-subcommand-subcommand-use-li","errorCode":null,"errorMessage":"Unknown worktree subcommand: {subcommand}. Use: list, add, remove, prune","messagePattern":"Unknown worktree subcommand: (.+?)\\. Use: list, add, remove, prune","errorType":"validation","errorClass":"anyhow::Error","httpStatus":null,"severity":"error","filePath":"crates/zeroclaw-tools/src/git_operations.rs","lineNumber":848,"sourceCode":"\n                self.run_git_command(&[\"worktree\", \"remove\", worktree_path], working_dir)\n                    .await?;\n                Ok(ToolResult {\n                    success: true,\n                    output: format!(\"Worktree removed: {worktree_path}\").into(),\n                    error: None,\n                })\n            }\n            \"prune\" => {\n                self.run_git_command(&[\"worktree\", \"prune\"], working_dir)\n                    .await?;\n                Ok(ToolResult {\n                    success: true,\n                    output: \"Worktree prune completed\".to_string().into(),\n                    error: None,\n                })\n            }\n            _ => anyhow::bail!(\n                \"Unknown worktree subcommand: {subcommand}. Use: list, add, remove, prune\"\n            ),\n        }\n    }\n}\n\n#[async_trait]\nimpl Tool for GitOperationsTool {\n    fn name(&self) -> &str {\n        \"git_operations\"\n    }\n\n    fn description(&self) -> &str {\n        \"Perform structured Git operations (status, diff, log, branch, commit, add, checkout, stash, worktree). Provides parsed JSON output and integrates with security policy for autonomy controls.\"\n    }\n\n    fn parameters_schema(&self) -> serde_json::Value {\n        json!({","sourceCodeStart":830,"sourceCodeEnd":866,"githubUrl":"https://github.com/zeroclaw-labs/zeroclaw/blob/88bb9c8533fc57ed7a03e36ca7c9ed2bf8336dcc/crates/zeroclaw-tools/src/git_operations.rs#L830-L866","documentation":"The git worktree tool's subcommand match covers exactly \"list\", \"add\", \"remove\", and \"prune\"; any other string falls through to the bail 'Unknown worktree subcommand: {subcommand}. Use: list, add, remove, prune'. This is a vocabulary restriction relative to the git CLI, which also supports lock, unlock, move, and repair — those are intentionally not exposed by this tool. The check is case-sensitive and runs after the missing-parameter check, so the value is guaranteed to be a non-empty string here.","triggerScenarios":"Calling with {\"subcommand\": \"lock\"}, {\"subcommand\": \"unlock\"}, {\"subcommand\": \"move\"}, or {\"subcommand\": \"repair\"} — valid git worktree subcommands the tool does not implement. Also typos and case variants: \"List\", \"rm\", \"delete\", \"prune \" with trailing space (trailing spaces make it a different string, though leading/trailing whitespace inside the JSON string is not trimmed).","commonSituations":"A developer ports a workflow that relied on `git worktree lock` before a backup; an agent infers subcommands from git's man page instead of the tool's schema; scripted cleanup tries \"rm\" as a shorthand for remove.","solutions":["Use exactly one of: list, add, remove, prune (lowercase).","For lock/unlock/move/repair, fall back to invoking git directly through a shell tool if your policy allows it — this tool will not grow them via argument tricks.","For removing a worktree, the supported spelling is \"remove\" (not \"rm\" or \"delete\").","When enumerating capabilities programmatically, treat the error's listed vocabulary as the schema of record."],"exampleFix":"// before\nlet args = serde_json::json!({ \"subcommand\": \"lock\", \"worktree_path\": \"/tmp/zc-feature\" });\n// tool bails: Unknown worktree subcommand: lock. Use: list, add, remove, prune\n\n// after: lock/move are not exposed; remove is the supported cleanup path\nlet args = serde_json::json!({ \"subcommand\": \"remove\", \"worktree_path\": \"/tmp/zc-feature\" });","handlingStrategy":"type-guard","validationCode":"fn build_worktree_args(subcommand: &str, path: Option<&str>) -> Option<serde_json::Value> {\n    WORKTREE_SUBCOMMANDS.contains(&subcommand).then(|| {\n        let mut args = serde_json::json!({ \"subcommand\": subcommand });\n        if let Some(p) = path { args[\"worktree_path\"] = serde_json::json!(p); }\n        args\n    })\n}","typeGuard":"const WORKTREE_SUBCOMMANDS: &[&str] = &[\"list\", \"add\", \"remove\", \"prune\"];\nfn is_supported_worktree_subcommand(cmd: &str) -> bool {\n    WORKTREE_SUBCOMMANDS.contains(&cmd)\n}","tryCatchPattern":"match tool_result {\n    Err(e) if e.to_string().starts_with(\"Unknown worktree subcommand\") => {\n        // the subcommand exists in git but not here; route lock/unlock/move to a shell tool or reject\n    }\n    other => other,\n}","preventionTips":["Restrict your UI/agent schema to the four exposed subcommands; do not proxy raw git vocabulary.","Map common shorthands before calling: rm->remove, new->add.","Keep an allowlist constant in the caller synced with the error text's vocabulary."],"tags":["git","worktree","unsupported-operation","validation","zeroclaw-tools"],"backgroundTag":"unsupported-operation","analyzedSha":"88bb9c8533fc57ed7a03e36ca7c9ed2bf8336dcc","analyzedAt":"2026-08-23T01:07:41.857Z","schemaVersion":2},"datasetVersion":"2026-08-23T08:06:27.607Z"}