biber hangs forever when a name list contains an empty name (e.g. `author = {Doe, Jane and ,}`)
@plk is already working on this.
Since Oct 25, 2026.
Assessment
- Difficulty
- 2/5
- Estimated time
- 1-3 hours
- Newbie friendliness
- 69/100
Research direction
Start with Biber::DataList::set_uniquename in lib/Biber/DataList.pm and inspect how it marks uniqueness data as changed when the current value is undefined. Reproduce the hang with the minimal test.bib example and run the relevant Biber test suite; done means malformed names terminate and produce a .bbl without changing output for existing cases.
Written by the indexing model from the issue text.
Description
🤖 This issue was identified by Claude Opus 5.5, and the text below is entirely written by Claude Opus 5.5
biber never terminates when a name in the labelname list has no name parts. The .bbl stays empty, and nothing is written to the log after the data source is read. A stray comma in a name list is enough, which is easy to get from exported or hand-edited .bib files.
Minimal example
test.bib:
@misc{key,
author = {Doe, Jane and ,},
title = {Title},
}
test.tex:
\documentclass{article}
\usepackage[style=authoryear]{biblatex}
\addbibresource{test.bib}
\begin{document}
\cite{key}
\printbibliography
\end{document}
pdflatex test && biber test: biber 2.22 (TeX Live 2026, macOS) is still running when killed after 30 seconds. The last log line is Found BibTeX data source 'test.bib', and test.bbl is left empty.
Other inputs that hang the same way:
author = {,};author = {family=Doe, given="Ja};- a granular XDATA reference to a missing entry,
author = {xdata=missing-author}.
Cause
In Biber::generate_uniquename, a name with no name parts has empty namestrings and namedisschema. So it ends up calling
$dlist->set_uniquename($nlid, $nid, $namedisschema->[0]) # undef
and Biber::DataList::set_uniquename sets the "changed" flag whenever the current value is undefined:
if (not defined($currval) or not Compare($currval, $s)) {
$self->set_unul_changed(1);
}
The stored value stays undef, so every pass of the while ('true') loop in Biber::uniqueness sees a change and runs again.
Suggested fix
Data::Compare already treats undef/undef as equal and undef/value as different, so the defined test can go:
--- a/lib/Biber/DataList.pm
+++ b/lib/Biber/DataList.pm
@@ -495,7 +495,7 @@
my $currval = $self->{state}{namelistdata}{$nlid}{$nid}{un};
# Set modified flag to positive if we changed something
- if (not defined($currval) or not Compare($currval, $s)) {
+ if (not Compare($currval, $s)) {
$self->set_unul_changed(1);
}
$self->{state}{namelistdata}{$nlid}{$nid}{un} = $s;
With this change, all of the inputs above terminate and produce a .bbl. I also ran the patched biber (from source, perl 5.42) over 776 test documents: the biblatex example files, the biber test suite's control files, and documents for the standard and contributed styles. The output was byte-identical to unpatched 2.22 in every case.
The code is unchanged on dev (df6438f). As an extra safeguard, the loop in Biber::uniqueness could also stop with a warning after some large number of passes, since real documents converge in two or three.
- Dominant language
- TeX
- Stars
- 396
- Forks
- 40
- Avg merge
- 8h 3m
- Merged PRs (30d)
- 1
Getting set up
This project ships no dev container, Dockerfile or contributing guide, so setting up is up to you: start from its README, and see our first-contribution guide for the general steps.
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
More from plk/biber
-
`singletitle`/`uniquetitle`/`uniquework` only ignore entries whose `options` field contains the literal token `skipbib`; `skipbib=true` and `dataonly` still countPossibly taken @plk claimed this 2 days ago. OpenBug fixedindev
Difficulty 2/5 1-3 hours Newbie friendliness 72/100
-
Filtered lists (e.g. the shorthand list) get every set and set member re-added once any set passes the filterPossibly taken @plk claimed this 2 days ago. OpenBug fixedindev
Difficulty 2/5 1-3 hours Newbie friendliness 60/100
-
`--output-fieldcase=Upper` (any non-lowercase spelling) and an invalid `output_fieldcase` in `biber.conf` crash biberPossibly taken @plk claimed this 3 days ago. OpenBug fixedindev
Difficulty 2/5 1-3 hours Newbie friendliness 72/100
-
`presort` values are used as a regex: `presort = {a(b}` crashes biber, and `|`, `+`, `?` give the wrong `sortinit`Possibly taken @plk claimed this 3 days ago. OpenBug fixedindev
Difficulty 2/5 1-3 hours Newbie friendliness 78/100
-
Range length wrong when an abbreviated range end contains a 0 (`pages = {315-20}` gives `\range{pages}{11}`)Possibly taken @plk claimed this 10 days ago. OpenBug fixedindev
Difficulty 2/5 1-3 hours Newbie friendliness 78/100
Similar issues
-
[fullsend] E2E: scorecard — filecheck GitLab entity metrics unavailable due to initialDelay timingOpene2e-failure ready-to-code
Difficulty 2/5 1-3 hours Newbie friendliness 75/100
redhat-developer/rhdh-plugin-export-overlays#4698 · 1 comment ·
Maintainers usually reply within 1 day
-
Difficulty 2/5 1-3 hours Newbie friendliness 88/100
devswha/herdr-web-ui#2884 ·
-
Difficulty 2/5 1-3 hours Newbie friendliness 79/100
Maintainers usually reply within 1 day
-
.NET good first issue testing
Difficulty 2/5 1-3 hours Newbie friendliness 76/100
HelloblueAI/HelloblueGK#311 ·
Maintainers usually reply within 1 day
-
Difficulty 2/5 1-3 hours Newbie friendliness 78/100
Maintainers usually reply within 1 day