gitbutlerapp/gitbutler · warning

no illformed UTF8

Error message

no illformed UTF8

What it means

After serializing a reflog line's gix signature into bytes, serialize_line() asserts the bytes are UTF-8 via std::str::from_utf8(&sig).expect("no illformed UTF8"). Unlike its sibling expect one line up, this one is genuinely reachable: gix signatures preserve raw bytes (e.g. latin-1 author names), and reflog files written by git can legitimately contain such non-UTF-8 identities.

Source

Thrown at crates/gitbutler-oplog/src/reflog.rs:158

        log.push_str(&serialize_line(reflog_line));
        log.push('\n');
    }

    log
}

fn serialize_line(line: gix::refs::file::log::LineRef<'_>) -> String {
    let mut sig = Vec::new();
    line.signature
        .write_to(&mut sig)
        .expect("write to memory succeeds");

    format!(
        "{} {} {}\t{}",
        line.previous_oid,
        line.new_oid,
        std::str::from_utf8(&sig).expect("no illformed UTF8"),
        line.message
    )
}

#[cfg(test)]
mod set_target_ref {
    use std::str::FromStr;

    use but_testsupport::{CommandExt, git_at_dir};
    use gix::refs::file::log::LineRef;
    use pretty_assertions::assert_eq;
    use tempfile::tempdir;

    use super::{
        GITBUTLER_COMMIT_AUTHOR_EMAIL, GITBUTLER_COMMIT_AUTHOR_NAME, ReflogCommits,
        set_reference_to_oplog,
    };

View on GitHub (pinned to caf1f223d3)

Solutions

  1. Find the offending ref: check the panic backtrace and scan .git/logs entries with `grep -Pxv '.*' .git/logs/refs/...` (or grep for bytes 0x80-0xFF)
  2. Fix the identity (set user.name/user.email to UTF-8 values) and rewrite or clear the affected reflog (.git/logs/<ref>) so new entries are clean
  3. Switch the code to String::from_utf8_lossy(&sig) so non-UTF-8 bytes are replaced rather than panicking (see exampleFix)

Example fix

// before
std::str::from_utf8(&sig).expect("no illformed UTF8")

// after
String::from_utf8_lossy(&sig)
Defensive patterns

Strategy: fallback

Validate before calling

// Scan a reflog for non-UTF-8 bytes before snapshotting it
fn reflog_is_utf8(path: &std::path::Path) -> bool {
    std::fs::read(path)
        .map(|bytes| std::str::from_utf8(&bytes).is_ok())
        .unwrap_or(false)
}

Try / catch

// Lossy conversion keeps the snapshot alive on legacy encodings
let sig_str = String::from_utf8_lossy(&sig);

Prevention

When it happens

Trigger: Computing the oplog/reflog snapshot for a ref whose reflog lines contain non-UTF-8 bytes in the identity (name/email portion): repos authored on systems with legacy single-byte locales, or reflog files containing binary garbage.

Common situations: Windows machines configured with latin-1 user names, old repositories migrated forward, reflog files corrupted or hand-edited, or users whose git identity contains non-UTF-8 bytes. Surfaces whenever GitButler reads the reflog to build undo history.

Related errors


AI-assisted analysis of gitbutlerapp/gitbutler@caf1f223d3 (2026-08-20). Data as JSON: /api/errors/702f16f1cfbe92e5. Report an issue: GitHub.