{"record":{"id":"4c4ca45298347785","repo":"gitbutlerapp/gitbutler","slug":"cannot-compute-diff-specs-for-worktree-name","errorCode":null,"errorMessage":"Cannot compute diff specs for worktree `{name}`","messagePattern":"Cannot compute diff specs for worktree `(.+?)`","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"crates/but/src/utils/diff_specs.rs","lineNumber":90,"sourceCode":"                anyhow::bail!(\"Cannot compute diff specs for branch `{}`\", branch.name)\n            }\n            CliId::AnonymousSegment(segment) => {\n                anyhow::bail!(\"{}\", anonymous_segment_error(&segment.id))\n            }\n            CliId::Commit {\n                commit:\n                    CommitId {\n                        commit_id,\n                        change_id: _,\n                    },\n                id: _,\n            } => self.push_changes_from_commit(*commit_id),\n            CliId::Uncommitted { id: _ } => self.push_changes_from_uncommitted_area(),\n            // A worktree's uncommitted area is expanded into its files during\n            // resolution, so the builder only ever sees hunks that already come from\n            // its own repo. The reference holds no changes at all.\n            CliId::Worktree { name, .. } | CliId::WorktreeUncommitted { name, .. } => {\n                anyhow::bail!(\"Cannot compute diff specs for worktree `{name}`\")\n            }\n            CliId::Stack { .. } => {\n                anyhow::bail!(\"Cannot compute diff specs for stacks\")\n            }\n            CliId::CommittedHunk(_) => {\n                anyhow::bail!(\"Cannot compute diff specs for committed hunks\")\n            }\n        }\n    }\n\n    pub fn push_changes_from_uncommitted(\n        &mut self,\n        uncommitted: &UncommittedHunkOrFile,\n    ) -> anyhow::Result<()> {\n        // Specs are built against one checkout's repository, so a hunk from\n        // another would silently address the wrong files. Operations that support\n        // worktree sources validate the selection and construct the builder via\n        // [`Self::for_change_source`]; the rest read the main worktree and refuse","sourceCodeStart":72,"sourceCodeEnd":108,"githubUrl":"https://github.com/gitbutlerapp/gitbutler/blob/58e5313667b857ef39a730e380af31816a7b1768/crates/but/src/utils/diff_specs.rs#L72-L108","documentation":"Diff specs cannot be computed for a whole worktree or its uncommitted area: during id resolution a worktree's uncommitted area is already expanded into its individual files, and the worktree reference itself holds no changes. The builder therefore rejects both `CliId::Worktree` and `CliId::WorktreeUncommitted` ids.","triggerScenarios":"Passing a worktree id or worktree-uncommitted id to an operation that calls `push_changes_from_id`; per the source comment, operations that do support worktree sources must construct the builder via `DiffSpecsBuilder::for_change_source` instead.","commonSituations":"Targeting a linked worktree with a command that only reads the main worktree; scripting against `but worktree`/status output and using the worktree id where a file or hunk id is required.","solutions":["Use ids of the worktree's individual files/hunks instead of the worktree id","If worktree-source support is needed, construct the builder with `for_change_source` rather than the default main-worktree builder","Operate from inside the worktree so its changes appear as the normal uncommitted area"],"exampleFix":null,"handlingStrategy":"validation","validationCode":"if matches!(id, CliId::Worktree{..} | CliId::WorktreeUncommitted{..}) {\n    eprintln!(\"worktree ids are not a diff-spec source; use its file/hunk ids\");\n    return Ok(());\n}","typeGuard":"fn is_worktree_id(id: &CliId) -> bool { matches!(id, CliId::Worktree{..} | CliId::WorktreeUncommitted{..}) }","tryCatchPattern":"match result { Err(e) if e.to_string().starts_with(\"Cannot compute diff specs for worktree\") => { /* use file ids from the worktree */ }, other => other }","preventionTips":["Expand worktrees into their file/hunk ids before building diffs","Use `for_change_source` when an operation must support worktree sources","Run commands inside the worktree to address its changes directly"],"tags":["cli","worktree","diff"],"backgroundTag":"unsupported-operation","analyzedSha":"58e5313667b857ef39a730e380af31816a7b1768","analyzedAt":"2026-09-18T06:50:32.052Z","contentChangedAt":"2026-09-18T06:50:32.052Z","schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}