GitoxideLabs/gitoxide · error

a reference line contains an empty name

Error message

a reference line contains an empty name

What it means

After splitting the body of a `(…)` reference line on unquoted commas, each comma-separated item must be a non-empty name. `parse_ref_line` throws this error when an item is empty or whitespace-only, which happens with leading/trailing/duplicated commas in the reference list.

Solutions

  1. Remove the extra comma that produced the empty entry.
  2. Delete the whole `(…)` line if no references should be carried.
  3. Ensure each comma-separated item contains exactly one reference name.

Example fix

// before
(refs/heads/main, , refs/tags/v1)

// after
(refs/heads/main, refs/tags/v1)
Defensive patterns

Strategy: validation

Validate before calling

// Rust: reject empty items in a comma-separated reference list before parsing
fn ref_items_valid(line: &str) -> bool {
    line.trim_start_matches('(').trim_end_matches(')')
        .split(',')
        .all(|item| !item.trim().is_empty())
}

Try / catch

match parse_plan(&repo, text) {
    Ok(plan) => apply(plan),
    Err(e) if e.to_string().contains("contains an empty name") => {
        eprintln!("Remove the stray comma in the (…) reference line.");
        Err(e)
    }
    Err(e) => return Err(e),
}

Prevention

When it happens

Trigger: Calling `parse` with reference lines like `(,)`, `(name1,,name2)`, `(name1, )`, or `()` where an empty token remains after trimming.

Common situations: Deleting a name but leaving its comma; trailing comma left after removing the last entry; copy-paste artifacts adding an extra comma.

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


AI-assisted analysis of GitoxideLabs/gitoxide@e73179060b (2026-09-08). Data as JSON: /api/errors/eaaa7378b33aa605. Report an issue: GitHub.

Appendix: source

Thrown at gix-tix/src/edit/todo.rs:1107

        match byte {
            b'\\' if quoted => escaped = true,
            b'"' => quoted = !quoted,
            b',' if !quoted => {
                ranges.push(&body[start..index]);
                start = index + 1;
            }
            _ => {}
        }
    }
    if quoted || escaped {
        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(

View on GitHub (pinned to e73179060b)