[Tex/LaTex] Biblatex produces incomplete .bcf with biber backend

biberbiblatexbibtexdocumentclass-writing

I am developing a latex documentclass and am having a rather strange problem with biblatex and the biber backend. As described here, when I run pdflatex and then biber on this minimal.tex file:

\documentclass{quantumarticle}
\usepackage[backend=biber]{biblatex}
\addbibresource{minimal.bib}
\begin{document}
\cite{Foo2035}
\printbibliography
\end{document}

with this minimal.bib

@article{Foo2035,
  author = {Foo, Bar},
  journal = {Journal},
  year = {2010},
  title = {Title},
  doi = {doi},
}

Biber produces the following error (logged to minimal.blg):

[0] Config.pm:354> INFO - This is Biber 2.6
[0] Config.pm:357> INFO - Logfile is 'minimal.blg'
[33] biber:302> INFO - === Tue Dec 13, 2016, 16:21:37
[46] Utils.pm:180> ERROR - minimal.bcf is malformed, last biblatex run probably failed. Deleted minimal.bbl
[46] Biber.pm:114> INFO - ERRORS: 1

Indeed, inspecting minimal.bcf reveals that biblatex did not close the <bcf:section> tag in minimal.bcf and did not include a <bcf:sortlist>. The file ends with

  [...]
  <bcf:section number="0">
    <bcf:citekey order="1">Foo2035</bcf:citekey>

Simply adding the lines

  </bcf:section>
</bcf:controlfile>

and then running biber again makes the error go away and a subsequent pdflatex run produces the expected output.

Replacing quantumarticle with the standard article class, on which my class is based, resolves the problem.

Of course I do not expect you to go through my whole documentclass to find the mistake, but I don't even know where to start looking for the problem.

What could possibly make biblatex write an incomplete .bcf file without throwing any error?

Best Answer

The issue is ltxgrid, or rather the ltxutil package it loads: you can see this with

\documentclass{article}
\usepackage{etoolbox}
\usepackage{ltxgrid}
\usepackage{biblatex}
\addbibresource{minimal.bib}
\begin{document}
\cite{Foo2035}
\printbibliography
\end{document}

where the order of packages is important.

Tracing carefully, you find that ltxutil (which doesn't like being loaded without ltxgrid) does

\def\enddocument{%
 \let\AtEndDocument\@firstofone
 \@enddocumenthook
 \@checkend{document}%
 \clear@document
 \check@aux
 \deadcycles\z@
 \@@end
}%

i.e. an arbitrary redefinition of the macro. If you revert this

\documentclass{article}
\usepackage{etoolbox}
\let\savedenddocument\enddocument
\usepackage{ltxgrid}
\let\enddocument\savedenddocument
\usepackage{biblatex}
\addbibresource{minimal.bib}
\begin{document}
\cite{Foo2035}
\printbibliography
\end{document}

the issue goes away (you then get some odd lines in the terminal).

The problem is that both etoolbox and ltxutil are trying to set up various hooks. With etoolbox, code is added by patching with a fallback if it fails, so there is no error if etoolbox is loaded first. On the other hand, as ltxutil simply zaps \enddocument, anything installed by etoolbox is lost.

All of this bites biblatex as it puts material into hooks provided by etoolbox, so when the hook insertion is lost the material is effectively too.


You can get back the writing from biblatex by adding

\makeatletter
\patchcmd\enddocument
  {\deadcycles}
  {\let\AfterEndDocument\@firstofone    
   \@afterenddocumenthook
   \deadcycles}
  {}
  {\AtEndDocument{%
     \let\etb@@end\@@end
     \def\@@end{%
       \let\AfterEndDocument\@firstofone
       \@afterenddocumenthook
       \etb@@end}}}
\makeatother

(which is what etoolbox does in the first place) after loading ltxgrid: this re-introduces the hook used by biblatex. You will find some odd lines in your terminal output, related to the fact that the normal mechanisms for writing lot, lof, etc. have been altered by ltxgrid. (It's all about altering how things go onto the main vertical list, so that's not surprising: see xgalley for the team approach in this area, which is much more non-compatible with any code that doesn't know about it!)