Типичные ошибки и отладка

Урок учит читать сообщения об ошибках и быстро находить причину неудачной компиляции.

Ошибка компиляции в LaTeX всегда указывает на строку (l.NN) и тип проблемы (после !); научиться их читать — половина успеха в работе с LaTeX.

Рано или поздно документ не соберётся. Паниковать не нужно: у LaTeX осмысленные сообщения, и большинство ошибок относится к десятку типовых ситуаций. Разберём самые частые.

Несбалансированные скобки и окружения

Самая частая беда — забытая закрывающая скобка } или незакрытое окружение:

! Missing } inserted.
! \begin{itemize} on input line 12 ended by \end{document}.

Первое сообщение — где-то не хватает }. Второе — окружение itemize открыто на строке 12, но не закрыто \end{itemize}. Лечение: проверить парность {} и каждого \begin/\end. Хороший редактор подсвечивает парные скобки.

Неизвестная команда

! Undefined control sequence.
l.42 \includegrafics
                     {plot.png}

Команда \includegrafics не существует — опечатка (правильно \includegraphics) или забыт пакет (graphicx). Две причины «Undefined control sequence»: опечатка в имени или неподключённый пакет.

Забыт матрежим

! Missing $ inserted.
l.30 Формула x^2

Вы написали x^2 в обычном тексте — символ ^ работает только в матрежиме. Оберните в $...$. Эта же ошибка возникает при незакрытом $.

Переполнение строки (Overfull hbox)

Это предупреждение, а не ошибка — документ соберётся, но строка вылезает за поле:

Overfull \hbox (15.0pt too wide) in paragraph at lines 50--52

Обычно причина — длинное слово, URL или формула, которые LaTeX не смог перенести. Лечение: разрешить перенос (пакет hyphenat или \- в слове), для URL использовать пакет url, для широкой таблицы — уменьшить или повернуть. Режим draft в опциях класса помечает такие места чёрной полосой на полях.

Стратегия отладки

  1. Читайте первую ошибку — последующие часто её следствия.
  2. Смотрите номер строки l.NN и сам файл .log.
  3. Если непонятно где — закомментируйте половину тела (% или \iffalse...\fi) и ищите методом деления пополам.
  4. После исправления удалите .aux и соберите заново, если ошибки «залипли».

Как работает под капотом

Движок читает исходник линейно и при встрече с чем-то невозможным останавливается, печатая контекст: что он пытался сделать (!-строка) и где (l.NN). Каскад ошибок возникает потому, что после первой проблемы движок «теряет нить» — например, незакрытая скобка ломает разбор всего, что идёт дальше. Поэтому правят сверху вниз по одной. Предупреждения о переполнениях — это сигналы алгоритма набора абзаца: он не нашёл способа разбить строки без выхода за поле и сообщает, насколько вылез.

Файл .log — главный источник правды

Сообщение, мелькнувшее в редакторе, — это лишь верхушка. Полная картина всегда в файле .log рядом с документом: туда движок пишет каждую загруженную пакетную строку, все предупреждения и контекст ошибок целиком. Если в IDE не видно деталей, откройте .log и найдите первый восклицательный знак ! — это первая фатальная ошибка. Полезная привычка — добавить в преамбулу \listfiles: тогда в конце .log появится таблица всех подключённых пакетов с их версиями и датами. Когда кто-то жалуется «у меня собирается, а у тебя нет», сравнение этих таблиц мгновенно показывает разницу в версиях — частую причину расхождений между двумя машинами или между локальной установкой и Overleaf.

Ещё две коварные ошибки

Сообщение Runaway argument означает, что аргумент команды «убежал» — обычно вы открыли { и не закрыли его, и движок проглатывал текст в поисках пары, пока не упёрся в пустую строку или конец абзаца. Ищите непарную скобку выше указанной строки. Ошибка File not found или LaTeX Error: File `...' not found говорит, что не найден либо подключаемый файл (картинка, \input-фрагмент), либо целый пакет. В первом случае проверьте имя и путь — регистр и расширение имеют значение, особенно на Linux; во втором — пакет не установлен в дистрибутиве, и его нужно доставить через менеджер пакетов TeX Live или MiKTeX. Эти две ошибки вместе с уже разобранными Missing $, Undefined control sequence и несбалансированными скобками покрывают подавляющее большинство реальных случаев.

Поиск делением пополам

Когда сообщение указывает не туда или ошибка явно «уехала» от настоящей причины, выручает метод деления пополам. Закомментируйте примерно половину тела документа — большой кусок текста удобно отключить, обернув его в \iffalse ... \fi, не расставляя % на каждой строке. Если ошибка исчезла, она в отключённой половине; если осталась — в оставшейся. Сужайте подозрительный участок вдвое за каждый прогон, и за несколько итераций вы локализуете проблему до пары строк. Тот же приём работает с преамбулой: временно отключайте по одному \usepackage, чтобы найти конфликтующий пакет. Конфликты версий и порядка загрузки пакетов — отдельный класс проблем; иногда помогает поменять пакеты местами или прочитать в .log, какой именно из них печатает предупреждение.

Частые ошибки

  • Чинить последнюю ошибку вместо первой — остальные часто исчезнут сами.
  • Игнорировать предупреждения Overfull — в печати это видимый дефект.
  • Не чистить .aux при «застрявших» странных ошибках после крупной правки.

Итоги

  • Ошибка указывает тип (после !) и строку (l.NN); читайте первую.
  • Топ-причины: несбалансированные {}/окружения, опечатки команд, забытый матрежим.
  • Overfull hbox — предупреждение о выходе за поле; лечится переносами и пакетами url.
Проверьте себя
1. С какой ошибки лучше начинать исправление?
AС последней в списке
BС первой — остальные часто являются её следствием
CС самой длинной
DПорядок не важен
2. Что означает «! Undefined control sequence»?
AЗакончилась память
BВстречена несуществующая команда: опечатка или неподключённый пакет
CОшибка в библиографии
DСлишком много страниц
3. Чем является сообщение Overfull \hbox?
AФатальной ошибкой, документ не соберётся
BПредупреждением: строка вылезает за поле, но документ собирается
CСообщением об успехе
DОшибкой библиографии