{"record":{"id":"eaaa7378b33aa605","repo":"GitoxideLabs/gitoxide","slug":"a-reference-line-contains-an-empty-name","errorCode":null,"errorMessage":"a reference line contains an empty name","messagePattern":"a reference line contains an empty name","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"gix-tix/src/edit/todo.rs","lineNumber":1107,"sourceCode":"        match byte {\n            b'\\\\' if quoted => escaped = true,\n            b'\"' => quoted = !quoted,\n            b',' if !quoted => {\n                ranges.push(&body[start..index]);\n                start = index + 1;\n            }\n            _ => {}\n        }\n    }\n    if quoted || escaped {\n        anyhow::bail!(\"a quoted reference name is not closed\");\n    }\n    ranges.push(&body[start..]);\n    let mut out = Vec::with_capacity(ranges.len());\n    for item in ranges {\n        let item = item.trim();\n        if item.is_empty() {\n            anyhow::bail!(\"a reference line contains an empty name\");\n        }\n        let (marked, item) = item.strip_prefix('@').map_or((false, item), |item| (true, item));\n        let encoded = item.as_bytes().as_bstr();\n        let (name, consumed) = gix::quote::ansi_c::undo(encoded)\n            .map_err(gix::Exn::into_error)\n            .context(\"could not unquote a reference name\")?;\n        if !encoded[consumed..].trim().is_empty() {\n            anyhow::bail!(\"a reference name has trailing data\");\n        }\n        if name.is_empty() {\n            anyhow::bail!(\"a reference name is empty\");\n        }\n        out.push((marked, name.into_owned()));\n    }\n    Ok(out)\n}\n\nfn resolve_ref_name(","sourceCodeStart":1089,"sourceCodeEnd":1125,"githubUrl":"https://github.com/GitoxideLabs/gitoxide/blob/e73179060badf27222d790981fac3f84c1830a7e/gix-tix/src/edit/todo.rs#L1089-L1125","documentation":"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.","triggerScenarios":"Calling `parse` with reference lines like `(,)`, `(name1,,name2)`, `(name1, )`, or `()` where an empty token remains after trimming.","commonSituations":"Deleting a name but leaving its comma; trailing comma left after removing the last entry; copy-paste artifacts adding an extra comma.","solutions":["Remove the extra comma that produced the empty entry.","Delete the whole `(…)` line if no references should be carried.","Ensure each comma-separated item contains exactly one reference name."],"exampleFix":"// before\n(refs/heads/main, , refs/tags/v1)\n\n// after\n(refs/heads/main, refs/tags/v1)","handlingStrategy":"validation","validationCode":"// Rust: reject empty items in a comma-separated reference list before parsing\nfn ref_items_valid(line: &str) -> bool {\n    line.trim_start_matches('(').trim_end_matches(')')\n        .split(',')\n        .all(|item| !item.trim().is_empty())\n}","typeGuard":null,"tryCatchPattern":"match parse_plan(&repo, text) {\n    Ok(plan) => apply(plan),\n    Err(e) if e.to_string().contains(\"contains an empty name\") => {\n        eprintln!(\"Remove the stray comma in the (…) reference line.\");\n        Err(e)\n    }\n    Err(e) => return Err(e),\n}","preventionTips":["When deleting a name, delete its comma too.","Never leave a trailing comma in `(a, b,)`-style lists.","Omit the whole reference line when no refs need carrying."],"tags":["parsing","refs","validation"],"backgroundTag":"empty-required-field","analyzedSha":"e73179060badf27222d790981fac3f84c1830a7e","analyzedAt":"2026-09-08T11:26:50.865Z","contentChangedAt":"2026-09-08T11:26:50.865Z","schemaVersion":2},"datasetVersion":"2026-09-16T04:17:20.429Z"}