# Teach me to debug

Ok, 35 years of programming has not prepared me to debug tex errors. It's painful. I can't create an MWE because the point is to be able to debug in place.

Everything was working well, I would compile to check, and if anything goes wrong, undo and then fix. Then all of a sudden, texworks reported an error on line 204. Line 204 had nothing to do with it. Then it crashed. When I restarted, now I can see that it is now showing line 203 of the aux file. Which looks like this:

ExploringEngineering4.8.aux: 203 Undefined Control Sequence
l.203 \@writfle
{toc}{\contentsline {chapter}{\numberline {58}Lab: SD Card}{...


When I go to the line of source that caused this error:

\lab{SD Card}

An SD card is a


This is not the first time \lab has been encountered, so if it were the definition of lab, it should have happened way before.

I need to learn how to debug these sorts of problems without deleting thousands of lines.

• The last token in the first code line of the error message is the undefined control sequence. This can often be seen in the .log file, because some IDE's might mingle up the error message in the GUI. If it is \@writfle, then probably the intended correct macro name is \@writefile. Then grep or similar tools can be used to find the source file location of the misspelled \@writfle. May 11 '16 at 4:53
• Upvoting. I love LaTeX, but it's debugging capabilities (its entire error handling system actually) is nightmarish for anyone who has spent time with a "real" programming language. May 11 '16 at 14:05
• Remember LaTeX's level of reporting can be increased by using some of the tracing commands, see tex.stackexchange.com/q/60491/15925 May 18 '16 at 6:42
• @Gabriel TeX's error-handling system is actually reasonably good, but the problem is that LaTeX is implemented as a set of macros on top of TeX, and these macros don't implement robust error-handling. (Which is reasonable given the limitations of TeX's programming facilities, but unfortunate.) So you get error messages from the underlying TeX engine in terms of the macros it sees, which may appear to have no connection to what you typed. Basically what's happening here in such situations is that LaTeX is a leaky abstraction. Jan 2 '17 at 9:43
• There are a few things one can do that generally help with debugging: (1) increase max_print_line to a very high value (100000 or whatever), to turn off line wrapping (see this) (2) understand the error message conventions, e.g. the fact that output is printed in 2 (or 3) of lines, with one line containing everything that has been read so far, and the next line containing the rest, (3) Make sure options like -file-line-error are set (4) Increase \errorcontextlines to get full context, (5) learn to look at the .log file, (6) the answers below … Nov 14 '20 at 0:06

Common Errors includes this annotated image of an error message:

You have the -file-line-error option on so you've also got filename:linenum at the start of the message, which is more useful.

The line containing the error is staggered at the point where TeX has stopped to complain. As Heiko mentioned in the comments, that provides something you can grep for in your source files (including any packages or classes that you've loaded).

There are a number of reasons for an error occurring in the .aux file:

• The build process was interrupted, corrupting the file.
• The .aux file was accidentally modified while viewing it in an editor (unlikely, but could happen).
• A command has been written to the .aux file that doesn't get defined until after the .aux file is read in at the start of the document.
• A command that writes information to the .aux file has an error in the code that's being written to the file, but not executed at that point in the document.

Anything in the .aux file that includes {toc}{\contentsline is typically produced through \addcontentsline, which is defined as:

\addtocontents {#1}{\protect \contentsline {#2}{#3}{\thepage }}


and \addtocontents is defined as:

\protected@write\@auxout{%
\let\label\@gobble
\let\index\@gobble
\let\glossary\@gobble}%
{\string\@writefile{#1}{#2}}


The fact that your error message is in the form

\@writfle
{toc}{\contentsline {chapter}


suggests that \lab isn't using \addcontentsline (or \addtocontents) but explicitly uses \protected@write\@auxout or something has badly messed the definition of \addtocontents or something has corrupted the .aux file after it's been created.

A quick test is to show the definition of \lab just before its problematic usage (remove the .aux file first):

\show\lab
\lab{SD Card}


This will act like an error message, but the transcript will show the definition of that command. (More info on \show.) Does it use \addcontentsline? If so, add \show\addtocontents to check if its usual definition has changed.

If previous instances of \lab have worked fine, then it's possible something has gone wrong between this instance and the last, so try building up or hacking down the bit between the previous \lab and this one.

• Ok, \show did the trick, but while I had changed the definition of \lab, I did it for the entire document. The fact that only this one caused a problem is slightly insane since there are dozens of labs! I backed off on the change, and will post a separate question for that horrid mess.
– Dov
May 11 '16 at 14:16
• No mention of \errorcontextlines? May 11 '16 at 20:13

In order to debug your LaTeX errors, you should be able to create a MWE if you do not see where the error comes from.

The best bet is to use a divide and conquer method. Cut in half the code and remove those part. As you stated, it is time consuming.

However, some tools exist in order to automatize this as the Delta-Debug algorithm. You have to adapt the script to your need and then you'll have less code as a result and so be able to debug easily.

• A language in which I have to do divide and conquer to debug on a document of thousands of lines is, at the very least, poor. I will not say useless because LaTeX clearly has value, but you can't tell me with a straight face that this is reasonable. I don't have to do this in Java, C++, perl, ...
– Dov
May 11 '16 at 12:02