gitbutlerapp/gitbutler · warning
valid commit that can be parsed: TODO - allow it to return e
Error message
valid commit that can be parsed: TODO - allow it to return errors?
What it means
CommitMessageBstr::message_bstr() for gix::Commit wraps gix's message_raw(), which returns Result because extracting the message re-validates the decoded commit; the expect asserts a parsed gix::Commit can always yield its raw message, and the message itself flags the gap ('TODO - allow it to return errors?'). It can only fail when the underlying commit object bytes are malformed or corrupted.
Source
Thrown at crates/gitbutler-commit/src/commit_ext.rs:31
/// Obtain the commit-message as bytes, but without assuming any encoding.
fn message_bstr(&self) -> &BStr;
}
impl CommitExt for gix::Commit<'_> {
fn change_id(&self) -> Option<ChangeId> {
let commit = self.decode().ok()?;
Headers::try_from_commit_headers(|| commit.extra_headers())?.change_id
}
fn is_conflicted(&self) -> bool {
but_core::Commit::try_from(self.clone()).is_ok_and(|commit| commit.is_conflicted())
}
}
impl CommitMessageBstr for gix::Commit<'_> {
fn message_bstr(&self) -> &BStr {
self.message_raw()
.expect("valid commit that can be parsed: TODO - allow it to return errors?")
}
}
View on GitHub (pinned to caf1f223d3)
Solutions
- Run `git fsck --full` in the affected repository to locate and repair/re-fetch corrupt objects
- On untrusted data, bypass the extension trait: call commit.message_raw()? yourself and propagate the error (see exampleFix)
- Change the trait method to return Result so the decode error surfaces instead of a panic (the acknowledged TODO)
Example fix
// before (caller side)
let msg = commit.message_bstr(); // panics inside on undecodable commit
// after
let msg = commit
.message_raw()
.context("commit message of undecodable commit object")?; Defensive patterns
Strategy: try-catch
Validate before calling
// Before rendering untrusted commits, check decodability
if commit.message_raw().is_err() {
// skip or quarantine this commit instead of rendering it
} Type guard
fn commit_message_decodable(commit: &gix::Commit<'_>) -> bool {
commit.message_raw().is_ok()
} Try / catch
// Skip the extension trait on untrusted objects; use the fallible API directly
let message = commit
.message_raw()
.context("undecodable commit message")?; Prevention
- Prefer commit.message_raw()? over message_bstr() when handling data from untrusted repos
- Run git fsck on repositories that feed external tooling
- Treat any decode failure as data corruption, not as a control-flow signal
When it happens
Trigger: Calling message_bstr() wherever but renders commit messages on a commit whose object fails gix's decode step: truncated objects, bit-rot in the ODB, or a hostile repository serving garbage under a valid-looking id.
Common situations: Repositories with object-database corruption (failing disks), malicious clones crafted to crash tooling, or partially-completed transfers materializing invalid commit objects.
Related errors
AI-assisted analysis of gitbutlerapp/gitbutler@caf1f223d3 (2026-08-20).
Data as JSON: /api/errors/111c92aa78b5b8e8.
Report an issue: GitHub.