GitoxideLabs/gitoxide · info
valid ASCII
Error message
valid ASCII
What it means
When printing index entry status, a change is mapped to a single status character which is converted to `&str` via `str::from_utf8` with an `.expect("valid ASCII")`. Since `change_to_char` only yields ASCII characters, this panics only if that invariant is broken by a future code change.
Solutions
- Verify `change_to_char` only returns ASCII status characters ('A', 'M', 'D', etc.).
- Refactor to return `char` or a static `&'static str` from `change_to_char` so the UTF-8 conversion cannot fail.
- If hit, inspect the byte value returned and fix the mapping table.
Example fix
// before
let char_storage = change_to_char(&change);
std::str::from_utf8(std::slice::from_ref(&char_storage)).expect("valid ASCII")
// after
fn change_to_char(c: &Change) -> &'static str { /* ... */ }
change_to_char(&change) Defensive patterns
Strategy: type-guard
Type guard
fn is_ascii(b: &u8) -> bool { *b < 0x80 }
// assert change_to_char output is ASCII before conversion Try / catch
// unreachable by design; refactor instead change_to_char(&change) // return &'static str directly
Prevention
- Return &'static str or char from change_to_char to make conversion infallible
- Add a unit test asserting all mapped status chars are ASCII
- Avoid str::from_utf8 on dynamically derived single bytes without a check
When it happens
Trigger: Calling `print_index_entry_status` (from `show`) where `change_to_char` returns a non-ASCII byte — currently unreachable; a regression in `change_to_char` would trigger it.
Common situations: None in practice for library users; only developers modifying the status-character mapping in gitoxide-core could hit this.
Understand the failure class
Background: "This is a bug, please report it": internal invariant violations, unreachable panics, and SNH errors explained — this error's family across 47 libraries.
Related errors
- successful iteration has outcome
- parser must have set some object value
- every parent is set only once
- attr itself
- BUG: hunks are never empty
AI-assisted analysis of GitoxideLabs/gitoxide@e73179060b (2026-09-08).
Data as JSON: /api/errors/c73c5837355cd63a.
Report an issue: GitHub.
Appendix: source
Thrown at gitoxide-core/src/repository/status.rs:229
progress.init(Some(out.worktree_index.entries().len()), gix::progress::count("files"));
progress.set(out.worktree_index.entries().len());
progress.show_throughput(start);
Ok(())
}
fn print_index_entry_status(
out: &mut dyn std::io::Write,
prefix: &Path,
rela_path: &BStr,
status: EntryStatus<(), gix::submodule::Status>,
) -> std::io::Result<()> {
let char_storage;
let status = match status {
EntryStatus::Conflict { summary, entries: _ } => as_str(summary),
EntryStatus::Change(change) => {
char_storage = change_to_char(&change);
std::str::from_utf8(std::slice::from_ref(&char_storage)).expect("valid ASCII")
}
EntryStatus::NeedsUpdate(_stat) => {
return Ok(());
}
EntryStatus::IntentToAdd => "A",
};
let rela_path = gix::path::from_bstr(rela_path);
let display_path = gix::path::relativize_with_prefix(&rela_path, prefix);
writeln!(out, "{status: >3} {}", display_path.display())
}
fn as_str(c: Conflict) -> &'static str {
match c {
Conflict::BothDeleted => "DD",
Conflict::AddedByUs => "AU",
Conflict::DeletedByThem => "UD",
Conflict::AddedByThem => "UA",View on GitHub (pinned to e73179060b)