GitoxideLabs/gitoxide · error · anyhow::Error
a reference name is empty
Error message
a reference name is empty
What it means
After ANSI-C unquoting, a reference item may decode to an empty name (e.g. an item that was only quotes: `""` or `"@"` with an empty inner value). Since an empty reference name is meaningless in a Git plan, `parse_ref_line` throws this error rather than inserting a placeholder ref.
Solutions
- Replace the empty quoted name with the actual reference full name, e.g. `refs/heads/main`.
- Remove the empty item (and its comma) from the reference line entirely.
- Fix the generating script/variable so a real ref name is emitted instead of `""`.
Example fix
// before
("", refs/tags/v1)
// after
(refs/heads/main, refs/tags/v1) Defensive patterns
Strategy: validation
Validate before calling
// Rust: reject items that unquote to empty names
fn item_name_nonempty(item: &str) -> bool {
!item.trim().trim_start_matches('@').trim_matches('"').is_empty()
} Try / catch
match parse_plan(&repo, text) {
Ok(plan) => apply(plan),
Err(e) if e.to_string().contains("reference name is empty") => {
eprintln!("Replace the empty quoted name with a real reference name.");
Err(e)
}
Err(e) => return Err(e),
} Prevention
- Never emit `""` placeholders in generated reference lists.
- Check that ref-name variables are set before templating the todo.
- Require full names like `refs/heads/<branch>` in reference lines.
When it happens
Trigger: Calling `parse` with reference items like `("")` or `("" , name2)` where the quoted name unquotes to the empty string.
Common situations: A placeholder `""` left in a generated or hand-edited reference list; a script emitting empty names when the ref variable is unset.
Understand the failure class
Background: "must not be empty", "cannot be empty" — required-field validation errors across open-source libraries — this error's family across 41 libraries.
Related errors
- a reference line contains an empty name
- we are called from a valid ref
- CommentChar must not contain a line ending
- duplicate Todo header
- duplicate Message header
AI-assisted analysis of GitoxideLabs/gitoxide@e73179060b (2026-09-08).
Data as JSON: /api/errors/866e13066d99f0b6.
Report an issue: GitHub.
Appendix: source
Thrown at gix-tix/src/edit/todo.rs:1118
anyhow::bail!("a quoted reference name is not closed");
}
ranges.push(&body[start..]);
let mut out = Vec::with_capacity(ranges.len());
for item in ranges {
let item = item.trim();
if item.is_empty() {
anyhow::bail!("a reference line contains an empty name");
}
let (marked, item) = item.strip_prefix('@').map_or((false, item), |item| (true, item));
let encoded = item.as_bytes().as_bstr();
let (name, consumed) = gix::quote::ansi_c::undo(encoded)
.map_err(gix::Exn::into_error)
.context("could not unquote a reference name")?;
if !encoded[consumed..].trim().is_empty() {
anyhow::bail!("a reference name has trailing data");
}
if name.is_empty() {
anyhow::bail!("a reference name is empty");
}
out.push((marked, name.into_owned()));
}
Ok(out)
}
fn resolve_ref_name(
repo: &gix::Repository,
refs: &mut Vec<rebase::ExpectedRef>,
input: &gix::bstr::BStr,
) -> Result<gix::refs::FullName> {
let mut matches = refs
.iter()
.filter(|reference| reference.editable && ref_display_name(&reference.name, refs).as_bstr() == input)
.map(|reference| reference.name.clone());
if let Some(name) = matches.next() {
if matches.next().is_some() {
anyhow::bail!("the shortened reference name is ambiguous");View on GitHub (pinned to e73179060b)