GitoxideLabs/gitoxide · error
is not a commit ID prefix
Error message
{value:?} is not a commit ID prefix What it means
`resolve_commit` validates that a todo value looks like a commit ID abbreviation: at least 4 ASCII hex characters. If the token given to a `pick`, `squash`, or `fork` heading is shorter than 4 characters or contains non-hex characters, parsing fails with this error before any repository lookup is attempted.
Solutions
- Use at least a 4-character hex prefix of the commit ID (a full ID also works).
- Fix typos: the token must match `^[0-9a-fA-F]{4,}$`.
- Copy the ID from the generated todo or `git log` output instead of typing it manually.
Example fix
// before pick abc fix the thing // after pick 1a2b3c4d fix the thing
Defensive patterns
Strategy: validation
Validate before calling
// Rust: validate a todo ID token before building the todo line
fn is_commit_id_prefix(v: &str) -> bool {
v.len() >= 4 && v.bytes().all(|b| b.is_ascii_hexdigit())
} Type guard
fn as_commit_id_prefix(value: &str) -> Option<&str> {
let v = value.trim();
(v.len() >= 4 && v.bytes().all(|b| b.is_ascii_hexdigit())).then_some(v)
} Try / catch
match resolve_commit(&repo, value) {
Ok(id) => use_id(id),
Err(e) if e.to_string().contains("is not a commit ID prefix") => {
eprintln!("{value:?} must be >=4 hex chars; copy the ID from the generated todo.");
Err(e)
}
Err(e) => return Err(e),
} Prevention
- Copy commit IDs from the generated todo or `git log --format=%H` rather than typing them.
- Use at least 4 hex characters; full 40-char IDs always work.
- Never put branch names, tags, or message words where a hex ID is expected.
When it happens
Trigger: Calling `parse` with todo lines whose ID token is e.g. `abc` (too short), contains typos like `1a2b3c4g`, is an empty string after `split_whitespace`, or is a branch name/subject rather than a hex ID.
Common situations: Hand-editing the todo and typing a too-short abbreviation; pasting a shortstat or message word where the ID belongs; locales/editors mangling hex characters.
Understand the failure class
Background: "Invalid ... format", "must be in format X", "does not look like a ..." — invalid argument format errors across CLI tools and libraries — this error's family across 17 libraries.
Related errors
- an editable commit is not connected to the selected base
- the rebase todo contains more than one @ command
- an empty commit needs a title
- the rebase todo has no fork heading
- the last fork section contains no commits
AI-assisted analysis of GitoxideLabs/gitoxide@e73179060b (2026-09-08).
Data as JSON: /api/errors/6e76b47db2b6410a.
Report an issue: GitHub.
Appendix: source
Thrown at gix-tix/src/edit/todo.rs:1063
let checkout = checkout_target.map(|target| rebase::PlanCheckout {
target,
reference: checkout_reference,
});
Ok(Some(Parsed {
plan: rebase::Plan {
base: state.onto,
scope: state.scope,
steps,
checkout,
expected_refs: state.expected_refs,
},
tips: state.tips,
}))
}
fn resolve_commit(repo: &gix::Repository, value: &str) -> Result<ObjectId> {
if value.len() < 4 || !value.bytes().all(|byte| byte.is_ascii_hexdigit()) {
anyhow::bail!("{value:?} is not a commit ID prefix");
}
let id = repo
.rev_parse_single(value)
.with_context(|| format!("could not resolve commit ID {value:?}"))?;
id.object()
.context("could not load a todo object")?
.try_into_commit()
.context("a todo ID does not name a commit")?;
Ok(id.detach())
}
fn parse_ref_line(line: &str) -> Result<Vec<(bool, BString)>> {
let body = line
.strip_prefix('(')
.and_then(|line| line.strip_suffix(')'))
.context("a reference line must be enclosed in parentheses")?;
let mut ranges = Vec::new();
let mut start = 0;View on GitHub (pinned to e73179060b)