{"record":{"id":"c54590807f07e6c3","repo":"gitbutlerapp/gitbutler","slug":"base-commit-must-exist-if-provided-base","errorCode":null,"errorMessage":"Base commit must exist if provided: {base}","messagePattern":"Base commit must exist if provided: (.+?)","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"crates/but-rebase/src/lib.rs","lineNumber":101,"sourceCode":"    /// that all other commits should be placed on top of.\n    /// If `None` this means the first picked commit will have no parents.\n    /// This means that the first [picked commit](Self::steps()) will be placed right on top of `base`.\n    ///\n    /// If the first pick refers to a merge-commit then we will have to prove it's connected to the `base` commit.\n    /// If that `base`, however, is also a new commit, we'd have no way of figuring out which parent in the picked merge\n    /// is replaced with `base` to know which commits are involved in the merge.\n    /// The `base_substitute` passed here is the commit that stands in for `base` in the original graph that the\n    /// picked merge commit is linked to.\n    pub fn new(\n        repo: &'repo gix::Repository,\n        base: impl Into<Option<gix::ObjectId>>,\n        base_substitute: Option<gix::ObjectId>,\n    ) -> Result<Self> {\n        let base = base.into();\n        if let Some(base) = base\n            && !repo.has_object(base)\n        {\n            bail!(\"Base commit must exist if provided: {base}\");\n        }\n        Ok(Self {\n            repo,\n            base,\n            base_substitute,\n            steps: Vec::new(),\n            rebase_noops: true, // default to always rebasing\n        })\n    }\n\n    /// Adds and validates a list of rebase steps.\n    /// Ordered oldest (parentmost) to newest (childmost). Reference steps refer to the commit that precedes them.\n    /// Note that `steps` will extend whatever steps were added before.\n    pub fn steps(&mut self, steps: impl IntoIterator<Item = RebaseStep>) -> Result<&mut Self> {\n        for step in steps {\n            self.validate_step(&step)?;\n            self.steps.push(step);\n        }","sourceCodeStart":83,"sourceCodeEnd":119,"githubUrl":"https://github.com/gitbutlerapp/gitbutler/blob/58e5313667b857ef39a730e380af31816a7b1768/crates/but-rebase/src/lib.rs#L83-L119","documentation":"Rebase::new accepts an optional base commit that the rebase builds on top of. If a base ObjectId is supplied, the library verifies the object exists in the repository before constructing the builder; otherwise later steps would fail confusingly. This fail-fast check reports an unknown base immediately.","triggerScenarios":"Calling Rebase::new(repo, base, base_substitute, ...) with Some(oid) where repo.has_object(oid) is false — a commit id not present in the local object database.","commonSituations":"Passing a commit id from another clone/remote without fetching it; typos or truncated SHAs; referencing a commit that was garbage-collected; stale workspace state after force-push.","solutions":["Fetch the missing commit (git fetch origin <sha>) so it exists locally.","Verify the base id with `git cat-file -e <oid>` before calling Rebase::new.","Pass None as the base if no base commit is required, or correct the stale id."],"exampleFix":"// before\nRebase::new(&repo, Some(stale_oid), None, steps)?;\n// after\nassert!(repo.has_object(stale_oid), \"base must exist\");\nRebase::new(&repo, Some(stale_oid), None, steps)?;","handlingStrategy":"validation","validationCode":"if let Some(base) = base {\n    if !repo.has_object(base) {\n        return Err(anyhow!(\"base commit {} missing locally; fetch first\", base));\n    }\n}","typeGuard":null,"tryCatchPattern":"match rebase_result {\n    Err(e) if e.to_string().starts_with(\"Base commit must exist\") => {\n        // fetch the missing oid then retry\n    }\n    other => other?,\n}","preventionTips":["Verify base ids with `git cat-file -e` before constructing a Rebase","Fetch commits referenced from other clones/remotes","Refresh base ids after upstream force-pushes"],"tags":["rebase","git","missing-object"],"backgroundTag":"invalid-argument-value","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"}