gitbutlerapp/gitbutler · error
cannot snapshot a null target commit id
Error message
cannot snapshot a null target commit id
What it means
When the oplog snapshots a project, `ProjectMeta` is converted into `SnapshotProjectMeta`; the project's target commit id must exist and must not be the null object id. A null target means the project has no target branch commit assigned, so the snapshot is refused rather than persisting meaningless metadata.
Source
Thrown at crates/gitbutler-oplog/src/oplog.rs:76
virtual_branches: VirtualBranches,
}
#[derive(serde::Deserialize)]
#[serde(rename_all = "camelCase")]
struct SnapshotTarget {
branch_name: String,
remote_name: String,
sha: String,
push_remote_name: Option<String>,
}
impl TryFrom<&ProjectMeta> for SnapshotProjectMeta {
type Error = anyhow::Error;
fn try_from(meta: &ProjectMeta) -> Result<Self> {
let target_commit_id = meta.target_commit_id_or_err()?;
if target_commit_id.is_null() {
bail!("cannot snapshot a null target commit id");
}
Ok(Self {
target_ref: meta.target_ref.as_ref().map(ToString::to_string),
target_commit_id: target_commit_id.to_string(),
push_remote: meta.push_remote.clone(),
})
}
}
impl TryFrom<SnapshotProjectMeta> for ProjectMeta {
type Error = anyhow::Error;
fn try_from(meta: SnapshotProjectMeta) -> Result<Self> {
let target_ref = meta
.target_ref
.map(|name| {
let name: gix::refs::FullName = name
.try_into()View on GitHub (pinned to caf1f223d3)
Solutions
- Set or reselect the project's target branch so `target_commit_id` is populated, then retry
- Verify project metadata: `target_commit_id_or_err()` must return a non-null oid before snapshotting
- If the target is set in the UI yet still null, reload the project / clear the cache and retry
Example fix
// before: snapshot attempted with no target oplog.create_snapshot(&ctx, ...)?; // bail: cannot snapshot a null target commit id // after: assign a target branch first set_target_branch(&ctx, "origin/main")?; oplog.create_snapshot(&ctx, ...)?;
Defensive patterns
Strategy: validation
Validate before calling
let meta = current_project_meta(&ctx)?;
let target = meta.target_commit_id_or_err()?;
if target.is_null() {
return Err(anyhow::anyhow!("project has no target commit; pick a target branch first"));
} Type guard
fn has_snapshot_ready_target(meta: &ProjectMeta) -> bool {
meta.target_commit_id.is_some_and(|id| !id.is_null())
} Try / catch
match oplog.create_snapshot(&ctx, /* ... */) {
Err(err) if err.to_string().contains("null target commit id") => { /* prompt to select a target branch */ }
other => other,
} Prevention
- Require target branch selection during project onboarding
- Validate ProjectMeta before starting undoable mutations
When it happens
Trigger: Creating an oplog snapshot (every user-facing mutation records one) for a project whose `target_commit_id` is null — e.g. a project added without selecting a target branch, or whose target assignment failed.
Common situations: Freshly onboarded projects where target branch selection was skipped; project metadata restored from backup or edited by hand missing the target; a stale project cache hiding the missing target.
Related errors
- targetRef in project_meta.toml is not a remote-tracking bran
- targetCommitId in project_meta.toml is null
- Invalid conflict stage '{}'
- snapshot checkout ref is not a local branch
- snapshot checkout commit is null
AI-assisted analysis of gitbutlerapp/gitbutler@caf1f223d3 (2026-08-20).
Data as JSON: /api/errors/6e2376223d1ad0bb.
Report an issue: GitHub.