{"record":{"id":"9fc7ce5989a3dd04","repo":"gitbutlerapp/gitbutler","slug":"bug-a-change-from-was-pushed-into-a-builder-reading","errorCode":null,"errorMessage":"BUG: a change from {} was pushed into a builder reading {}","messagePattern":"BUG: a change from (.+?) was pushed into a builder reading (.+?)","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"crates/but/src/utils/diff_specs.rs","lineNumber":114,"sourceCode":"                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\n        // worktree hunks here.\n        if uncommitted.source != self.source {\n            if let Some(name) = uncommitted.source.worktree_name() {\n                anyhow::bail!(\"Cannot operate on uncommitted changes in worktree {name} yet\");\n            }\n            anyhow::bail!(\n                \"BUG: a change from {} was pushed into a builder reading {}\",\n                uncommitted.source.describe(),\n                self.source.describe()\n            );\n        }\n        let hunks = uncommitted.hunks.iter().cloned();\n        self.push_hunks(hunks.map(|id_and_hunk| id_and_hunk.hunk))\n    }\n\n    pub fn push_changes_from_path_prefix(\n        &mut self,\n        hunks: &nonempty::NonEmpty<IdAndHunk>,\n    ) -> anyhow::Result<()> {\n        self.push_hunks(hunks.iter().map(|id_and_hunk| id_and_hunk.hunk.clone()))\n    }\n\n    pub fn push_changes_from_committed_file(\n        &mut self,","sourceCodeStart":96,"sourceCodeEnd":132,"githubUrl":"https://github.com/gitbutlerapp/gitbutler/blob/58e5313667b857ef39a730e380af31816a7b1768/crates/but/src/utils/diff_specs.rs#L96-L132","documentation":"Internal invariant violation: an `UncommittedChanges` from a change source that is neither equal to the builder's source nor a named worktree was pushed into the builder. This indicates a bug in how the change was resolved or routed (sources should either match or be a worktree handled by the earlier branch).","triggerScenarios":"`push_changes_from_uncommitted` sees `uncommitted.source != self.source` and `uncommitted.source.worktree_name()` returns None — i.e. a mismatched non-worktree source reached the builder, e.g. via `push_changes_from_id` with a wrongly attributed uncommitted id.","commonSituations":"Should not occur in normal use; encountered when a resolver returns uncommitted changes attributed to an unexpected source kind, or after internal refactors that change source tagging.","solutions":["Report this as a bug to the GitButler project with the command and reproduction steps","Verify ids come from the current `but status` output of the same workspace (stale output can misattribute sources)","Retry after refreshing resolution state; if reproducible, include `but` version in the report"],"exampleFix":null,"handlingStrategy":"try-catch","validationCode":"debug_assert_eq!(uncommitted.source, builder.source, \"mismatched change source pushed into diff-specs builder\");","typeGuard":null,"tryCatchPattern":"if let Err(e) = result {\n    if e.to_string().starts_with(\"BUG: a change from\") {\n        // collect diagnostics and report upstream; this is an internal invariant violation\n        report_bug(e);\n    } else { return Err(e.into()); }\n}","preventionTips":["Keep source attribution consistent through id resolution","Add assertions/tests covering non-worktree mismatched sources","Report occurrences with `but` version and reproduction steps"],"tags":["bug","invariant-violation","worktree"],"backgroundTag":"internal-invariant-violation","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"}