GitoxideLabs/gitoxide · error
expected exactly one hexadecimal commit ID
Error message
expected exactly one hexadecimal commit ID
What it means
`resolve_pasted_commit` validates that a pasted string is a non-empty, pure ASCII-hexadecimal token before resolving it against the repository with `rev_parse`. The `anyhow::ensure!` fires when the pasted text is empty or contains any non-hex character, since only a full hexadecimal commit ID is accepted in this UI path.
Solutions
- Paste only the raw hexadecimal commit ID (40 or 64 hex chars depending on the repo hash).
- Strip decorations/prefixes: copy just the OID, e.g. via `git rev-parse <name>` first.
- If you need to accept symbolic names or short hashes, extend validation in `resolve_pasted_commit` to try `rev_parse` with gix's built-in prefix handling instead of requiring full hex.
- Trim surrounding whitespace/newlines before passing the string (the code already trims, but the clipboard content must still be pure hex).
Example fix
// before
let pasted = "commit 1a2b3c4..."; // copied from git log
resolve_pasted_commit(&repo, pasted)?;
// after
let pasted = pasted.split_whitespace().last().expect("token from log line");
resolve_pasted_commit(&repo, pasted)?; Defensive patterns
Strategy: validation
Validate before calling
fn is_pasted_valid(pasted: &str) -> bool {
let h = pasted.trim();
!h.is_empty() && h.bytes().all(|b| b.is_ascii_hexdigit())
} Try / catch
match resolve_pasted_commit(&repo, pasted) {
Err(e) if e.to_string().contains("expected exactly one hexadecimal commit ID") => {
eprintln!("Paste a raw hexadecimal OID, not a branch name or decorated line");
}
res => res?,
} Prevention
- Copy only the bare OID column from `git log --format=%H`
- Resolve symbolic names with `git rev-parse <name>^{commit}` before pasting
- Trim clipboard content and strip `commit ` prefixes and decorations
- For scripting, prefer rev-parse of a ref over pasting IDs
When it happens
Trigger: Pasting into the interactive commit-pick flow a string that is empty, whitespace-only after trim, contains prefixes like `HEAD~1`, branch names, short refs, or any non-hex characters (gix-tix/src/lib.rs:7017).
Common situations: Copying `git log`-style lines that include `commit <sha>` prefixes or decorations; pasting symbolic names like `main` or `origin/main`; trailing punctuation or whitespace from a terminal; pasting a full OID with typos.
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
- Invalid pathspec - path must not be empty, not be excluded…
- specify at least one contact to run through the mailmap
- path does not name a file
- ' ' is not a valid configuration key
- we are called from a valid ref
AI-assisted analysis of GitoxideLabs/gitoxide@e73179060b (2026-09-08).
Data as JSON: /api/errors/2cb13d8540aeec0b.
Report an issue: GitHub.
Appendix: source
Thrown at gix-tix/src/lib.rs:7017
_ => None,
};
selected.map_or(CommandMenuInput::Handled, |id| {
CommandMenuInput::Submit(
commands
.iter()
.find(|command| command.id == id)
.expect("a submitted command came from the current catalog")
.action
.clone(),
)
})
}
}
}
fn resolve_pasted_commit(repository: &gix::Repository, pasted: &str) -> Result<gix::ObjectId> {
let hash = pasted.trim();
anyhow::ensure!(
!hash.is_empty() && hash.bytes().all(|byte| byte.is_ascii_hexdigit()),
"expected exactly one hexadecimal commit ID"
);
let object = repository
.rev_parse(hash.as_bytes().as_bstr())
.context("could not resolve pasted commit ID")?
.single()
.context("pasted commit ID is ambiguous")?
.object()
.context("could not read pasted object")?;
anyhow::ensure!(
object.kind == gix::object::Kind::Commit,
"pasted object is not a commit"
);
Ok(object.id)
}
fn diagnostic_key(character: char) -> KeyEvent {View on GitHub (pinned to e73179060b)