Перейти к основному содержимому

Коды ошибок

Все диагностики, которые может выдать TDC, по кодам. Загляните сюда, когда запуск остановился, а одного сообщения не хватило.

Как читать диагностику

В диагностике четыре части, и код — та из них, что не меняется между версиями: формулировку могут улучшить, TDC193 останется TDC193.

./run demo.tdc
error[TDC193]: "Naem" is not a declared sequence — it would be printed literally
--> demo.tdc:8:11
|
8 |     <line><data>${{Naem}}</data></line>
|           ^^^^^^^^^^^^^^^^^^^^^^
|
help: did you mean "Name"?
note: Declare it in <env>, or set a different inject= pattern if you really want the text ${{…}} in the output.
  • код — что пошло не так; не меняется от версии к версии;
  • место — файл, строка и колонка, с подчёркнутым виновником;
  • help: — догадка, что вы имели в виду, когда имя похоже на существующее;
  • note: — что с этим делать.

Проверка идёт до генерации, поэтому конфиг с ошибкой не даёт данных вообще, а не половину файла. Почти каждая диагностика здесь — ошибка, и она останавливает прогон: если конфиг попросил то, чего не получит, TDC отказывается, а не отдаёт данные, которые выглядят правильно, но таковыми не являются. Исключения — семь предупреждений, при которых прогон завершается: TDC136 (кривая строка <map> пропускается, а корректные продолжают действовать), TDC171 (файл пакета, шапка которого не даёт ему никакого адреса), TDC200 (оценка памяти большая, но всё же помещается), TDC216 (выражение, которое всегда истинно или всегда ложно), TDC221 (группа <uniq> или <distinct> с одним участником, которая ничего не ограничивает), TDC231 (пул, который никто не читает) и TDC234 (пул больше 100 000 членов). Каждое говорит об этом в своей строке ниже.

Номера раздаются примерно в том порядке, в каком конфиг проверяется — сперва структура, потом генераторы, потом всё, что построено сверху, — но номер это идентификатор, а не классификация. Ориентируйтесь на разделы ниже.

Структура документа

КодКогда срабатываетЧто делать
TDC001В файле нет корневого <tdc>Оберните всё в один <tdc>…</tdc>
TDC002У <tdc> нет дочернего <block>Добавьте <block> с раскладкой одной карточки
TDC003На <tdc> заданы и version, и vОставьте одно — это синонимы
TDC004Объявленная версия документа не похожа на версиюУкажите версию, которую поддерживает рантайм, например v="0.1" (значение новее рантайма даёт TDC005)
TDC005Файл требует версию новее этой сборкиОбновите TDC или понизьте объявленную версию
TDC010Прямо под <tdc> стоит тег, кроме <env> и <block>Перенесите его внутрь одного из двух
TDC013Тег вложен туда, где он не разрешёнСм. Теги — что во что можно класть
TDC014Тег, которому нужны дети, записан самозакрывающимсяПишите <env …></env>, а не <env …/> — дети молча пропали бы
TDC015У тега атрибут, который движок не читаетПрогон останавливается: конфиг просил то, чего не получил бы. Проверьте написание — в сообщении есть подсказка с ближайшим настоящим именем
TDC020count не целое неотрицательноеcount="1000"
TDC021В шаблоне inject нет места под %Маркеру нужен % под имя, например inject="[[%]]"

Последовательности

КодКогда срабатываетЧто делать
TDC030У тега, которому нужно имя, его нетДобавьте name="…"
TDC031Имя последовательности начинается с _Этот префикс отдан встроенным
TDC032Две последовательности с одним именемПереименуйте одну — ссылка была бы неоднозначной
TDC033Имя совпало со встроеннымВозьмите другое: встроенное всегда выигрывает
TDC034Значение parent не в форме Родитель.ЗначениеПишите обе части, например parent="Gender.Male"
TDC035Родительская последовательность объявлена после этойПоднимите родителя выше — разбор идёт сверху вниз
TDC214parent= называет составную последовательностьРодитель отбирается по значению, а группа полей своего значения не даёт
TDC036Внутри <sequence> нет <gen>Без генератора последовательность ничего не производит
TDC110выведен из обращения — безымянный <gen> рядом с именованным теперь собирает значение, а не считается ошибкой
TDC111Два поля одной составной последовательности с одним именемПереименуйте одно
TDC129<sequence> внутри тега уровня конфига не даёт там ничего пригодногоСм. Последовательности

Генераторы

КодКогда срабатываетЧто делать
TDC040У <gen> нет typeДобавьте type="…" — см. Генераторы
TDC041Тип неизвестен или не поддержан для встроенного <gen>Проверьте написание — TDC подскажет ближайшее имя
TDC050type="text" без valueЗадайте список, например value="a,b,c"
TDC051В percent больше значений, чем в списке valueПо одному проценту на значение
TDC052Элемент percent — не неотрицательное числоЗаполненные позиции — числа; пустая делит остаток поровну
TDC053Значения percent не дают в сумме 100Приведите к сумме 100 или оставьте позицию пустой под остаток
TDC060type="file" без srcУкажите файл в src
TDC061Файл не читаетсяПроверьте путь — он отсчитывается от конфига, либо используйте --data-path
TDC062column не разрешаетсяИмя из заголовка (column="email") или номер с единицы (column="2")
TDC064row без columnСвязке строк нужно знать, из какой колонки CSV тянуть
TDC065type="http" без srcУкажите адрес сервиса — src="http://127.0.0.1:5566/gen"
TDC066src — не http(s)-адресПишите http://… или https://…, с хостом и путём
TDC067in= называет то, что не объявлено вышеЗначение на строку берётся из более ранней <sequence>
TDC068on_error не fail и не emptyfail (по умолчанию) роняет прогон; empty оставляет ячейку пустой
TDC070type="template" без valueЗадайте адрес через точку, например value="person.lastName"
TDC071Адрес шаблона неизвестенПроверьте написание или поставьте пакет, который его даёт
TDC072value="date.range" без range, или параметр type="template", которого пакет не объявляетДобавьте range="…"; либо проверьте имя параметра — сообщение перечисляет допустимые
TDC073Устаревший range — не две корректные датыФормат YYYY.MM.DD - YYYY.MM.DD
TDC081Числовой диапазон записан неверноvalue="10..99"
TDC082first_zero не true и не falseДругих значений нет
TDC083length не число, не диапазон и не список через запятуюНапример length="8", length="6..9", length="4,6,8"
TDC084В percent на числовом value больше значений, чем допускает диапазонПо одному проценту на значение
TDC085Элемент percent на числе — не неотрицательное числоЗаполненные позиции — числа
TDC086percent на числе не даёт в сумме 100Приведите значения к сумме 100
TDC087include/exclude без числового диапазона в valueОни фильтруют диапазон, значит он должен быть
TDC088distribution вместе с несовместимым атрибутомИменованное распределение само задаёт розыгрыш
TDC089Параметры распределения неверныСм. Распределения
TDC090Атрибут, который обязан быть числом, им не являетсяПроверьте значение
TDC095type="regex" без valueШаблон кладётся в value
TDC096regex_max_length не положительное целоеНапример regex_max_length="64"
TDC097Регулярка не разбираетсяПочините шаблон — дальше идёт сообщение самого парсера
TDC098У type="symbol" заданы и value, и alphabet, либо ни одинЗадайте ровно один — набор в value или именованный alphabet
TDC099Именованный алфавит неизвестенСм. Символы
TDC128type="advanced_regex" без valueШаблон кладётся в value
TDC128(второе значение) default= или if= написаны на <case><mix> выбирает случай по проценту, <switch> — по ключу is; условий не спрашивает ни тот, ни другой. Для значений по условию используйте <sequence> с ветками <gen if="…">
TDC130Продвинутый шаблон не разбираетсяСм. Advanced regex

Выражения в if

КодКогда срабатываетЧто делать
TDC100Выражение не разбираетсяСм. Вывод и форматирование
TDC101Бинарный оператор не поддержанПоддержаны: == != === !== < > <= >= && || + - * /
TDC102Унарный оператор не поддержанПоддержаны: !, -, +
TDC103Использован вычисляемый доступ к полюРазрешены только простые имена
TDC215Имя в if=, которого нет ни у одной последовательностиОно читается как свой же текст: в одиночку ветка срабатывает всегда, в сравнении — никогда
TDC216(предупреждение) if="Seq.Value" называет значение, которого последовательность не выдаётВетка мёртвая. Именно предупреждение: сузить список намеренно — нормальная практика
TDC217Путь шаблона существует, но не для локали прогонаСообщение называет локаль; поставьте local= на <gen> или <env>, либо выберите путь, который есть в вашей локали
TDC218uniq="true" на последовательности без своих значений — <compute> читает другие, if= выбирает ветку на строкуПоставьте uniq= на те последовательности, которые она читает, либо оберните их в <uniq>
TDC219<compute> и <gen> в одной <sequence> — один из двух был бы выброшенВынесите <compute> в свою <sequence> и читайте разыгранную через <field>
TDC220uniq="true" на составном значении, склеивающем две и более разыгранные частиУ частей нет фиксированной ширины, поэтому уникальный набор частей не даёт уникальную строку: 9+15 и 91+5 — одни и те же три символа. Оставьте одну разыгранную часть или зафиксируйте ширины
TDC221(предупреждение) <uniq> или <distinct> вокруг менее чем двух <sequence>Группа ограничивает участников друг относительно друга, поэтому один участник не ограничивает ничего. Добавьте второго или напишите uniq="true" на самой последовательности

<pool>

См. Согласованные записи.

КодКогда срабатываетКак исправить
TDC222У <pool> нет name или нет countПул читается по имени и держит фиксированное число членов: <pool name="Doctors" count="30">
TDC223<pool count="…"> — не целое число не меньше 1Из пула, в котором ничего нет, нечего выдавать
TDC224<gen type="pool" value="X">, а пула <pool name="X"> нетВ сообщении перечислены объявленные пулы. Объявите его в том же <env>
TDC225filter="field == X", где обе стороны не могут совпасть ни на одном значенииОба списка написаны в конфиге, и они не пересекаются — значит каждая строка сужается до пустоты. Сообщение называет оба. Здесь докладывается только заведомое противоречие; редкое значение отвергается на той строке, где выпало
TDC226filter= читает Pool.field, а такого поля у пула нетВ сообщении перечислены поля пула. Неуточнённое незнакомое имя не трогают — язык выражений читает голое слово как литерал
TDC229${{Ref}}, где Ref разыгрывает целого членаЧлен — это запись, а не значение. Читайте поле: ${{Ref.lastName}}
TDC230<block>, тег обрамления или ещё один <pool> внутри <pool>Пул — это таблица, которую читают другие столбцы, а не то, что пишется в файл; и пулы не вкладываются
TDC231(предупреждение) <pool>, который не читает ни один <gen type="pool">Он строится целиком до первой строки и держится в памяти весь прогон, так что непрочитанный оплачен и выброшен. Прочитайте его или уберите
TDC232Имя в filter= является и полем пула, и последовательностьюПереименуйте одно из них. Уточнение одной стороны не помогает — второе имя всё равно читается как поле члена, и сравнение выйдет с самим собой
TDC234(предупреждение) Больше 100 000 членовПул держится в памяти весь прогон — около 320 байт на члена с четырьмя полями. Если имелось в виду число СТРОК, это count у <env>
TDC235Больше 1 000 000 членовПричина та же, но уже за гранью разумного прогона. Уменьшите пул или перенесите число в <env count="…">
TDC236(предупреждение) uniq="true" более чем на 100 000 строкВыбор без возврата означает, что нужно помнить выбранное, поэтому вся колонка остаётся в памяти и прогон не может стримить. Измерено: около 250 байт на значение — 2 000 000 строк стоят примерно 477 МБ. Работает; просто стоит делать это осознанно
TDC236Пул читает пул, объявленный ниже, или сам себяПулы строятся в порядке объявления, поэтому пул может читать только те пулы, что выше. Поднимите тот, который он читает. Из-за этого же порядка цикл между пулами записать нельзя
TDC241Два пула объявлены под одним именемПул берут по имени, поэтому двум одно имя не подходит. Раньше второй молча заменял первый, и единственным следом был TDC193 в блоке про поле, которого «нет»
TDC242anomaly или missing — не число в [0, 1]Оба задают ДОЛЮ значений: anomaly="0.05", missing="0.1"
TDC243anomaly на списке value, где нет ни одного числаАномалия умножает число, поэтому список слов вернётся неизменным
TDC244type="pattern" без points, src или upperРисунку нужна форма, откуда читать: points="0,0 1,5 2,3", файл в src или upper/lower для полосы

Нарастающие итоги

См. accumulate= и <gen type="running">.

КодКогда срабатываетКак исправить
TDC237accumulate= на генераторе без repeat=Накапливать нечего — списка нет. Добавьте repeat="N" или уберите accumulate=. (type="running" исключение: он накапливает по колонке)
TDC238accumulate= называет несуществующую операциюОдна из sum, min, max
TDC239<gen type="running"> не говорит, что (of=) или как (accumulate=) накапливатьНарастающий итог читает чужую колонку и сам ничего не разыгрывает, поэтому обязательны оба
TDC240of= или reset= называет колонку, объявленную не вышеИтог строится из колонки, которая уже существует — то же правило, что у parent=

<compute>

КодКогда срабатываетКак исправить
TDC180Тег внутри <compute>, которого нет в языке вычислений, или предикат, написанный вне <test>Тег назван в сообщении. Сверьтесь со справочником Язык вычислений — предикат вроде <eq> допустим только внутри <test>
TDC181<current>, <current_index> или <acc> вне тела итерацииОни существуют только внутри <do> (или <do> внутри <reduce>)
TDC182<var name="X"> не связан ни с одним <let>Оберните в <let name="X">…</let> или исправьте имя
TDC183У бинарной compute-операции не то число детей<add>, <subtract> … принимают ровно два операнда
TDC184У <choose> нет ветки <otherwise>Добавьте <otherwise> — ответ нужен каждой записи
TDC185<let name="X"> перекрывает внешнюю привязку с тем же именемПереименуйте одну — внутренняя скрыла бы внешнюю
TDC186<encode>: неизвестная кодировкаОдна из: base36, ascii, unicode, hex, binary, octal
TDC187У предиката нет обязательного ребёнка-обёртки<when> требует <test>, <choose><then>; сообщение называет пару
TDC188<int v="…"> — не целое числоПишите целое; для текста — <str v="…"/>
TDC189У <compute> больше одного <result>Оставьте один <result> — ранние были бы отброшены

<mix>, <switch>, фикстуры

КодКогда срабатываетЧто делать
TDC120У <mix> нет ни одного <case>Смеси нужны ветки, между которыми выбирать
TDC121В percent на <mix>/<switch> больше значений, чем ветокПо одному проценту на ветку
TDC122Элемент percent на <mix>/<switch> — не неотрицательное числоЗаполненные позиции — числа
TDC123percent на <mix>/<switch> не даёт в сумме 100Приведите значения к сумме 100
TDC124У <mix> ребёнок, отличный от <case>Там может стоять только <case>
TDC125У <case> неизвестный ребёнокРазрешены <data>, <gen>, <mix>
TDC131Внутри фикстуры вложен тег, который фикстуры не принимаютФикстуры держат только <line> и <data>
TDC132Внутри <line> стоит тег, которому там не местоБлок вывода — про раскладку, генераторы живут в <env>
TDC133У <switch> нет onНазовите последовательность, по которой идёт разбор
TDC134on называет несуществующую последовательность или её полеПроверьте имя — сообщение скажет, какая половина неверна
TDC135У <switch> нет записейДобавьте <map>, <case> или <default>
TDC136(предупреждение) Строка <map> не в форме КЛЮЧ:ЗНАЧЕНИЕ — плохая строка пропускается, а остальная карта продолжает действоватьПо одной паре на запись, через двоеточие
TDC137У <case> внутри <switch> нет isis — это ключ ветки
TDC245name у <switch>, записанного внутри <case>Вложенная форма даёт значение этой ветке; колонкой становится только <switch> уровня <env>

Даты

КодКогда срабатываетЧто делать
TDC150Задано только одно из from / toЛибо обе границы, либо ни одной
TDC151Значение даты не разбираетсяvalue="2020-01-01..2025-12-31", "birth", "today", "now"
TDC152Маркер в format неизвестенСм. таблицу маркеров
TDC153local называет локаль без данных о датахВстроены: en, es, ru, zh-cn
TDC154precision — не поддержанный шагСм. precision

Во время генерации

Эти возникают уже при генерации, а не при проверке: конфиг корректен, но сочетание выполнить нельзя.

КодКогда срабатываетЧто делать
TDC160row="…" на встроенном <gen>Связка строк требует <sequence>
TDC161Взвешенный выбор advanced_regex использован встроенноТочные проценты считаются по всей колонке — перенесите в <sequence>
TDC162У встроенного счётчика value или step не числоvalue="1" step="2"
TDC170Файл пакета данных не загружаетсяСообщение называет файл — см. Свой пакет данных
TDC171(предупреждение) Файл пакета данных не получает адреса, поэтому пропускаетсяДобавьте address: или locale: в шапку либо переместите файл в папку локали
TDC200(предупреждение) Оценка потребности в памяти — большая доля ОЗУ этой машины, прогон продолжаетсяДля очень больших наборов используйте mode="disk", память остаётся плоской
TDC201Оценка потребности в памяти превышает ОЗУ этой машиныУменьшите count, разбейте на пакеты или используйте mode="disk"
До трёх из них из конфига не добраться

TDC160, TDC161 и TDC162 описывают встроенный <gen> — написанный прямо внутри <line>, а не в <sequence>. Такую форму валидация отвергает раньше, кодом TDC131 (a <gen> is not allowed inside <line>) или TDC013, так что настоящий конфиг до них не доходит. Достать их можно только низкоуровневым экспортом render(parse(src).tree), который намеренно обходит непроверенное дерево. По той же причине их нет в четырёх портах: они собирают из конфига модель, куда такой <gen> просто некуда положить.

Форматирование и модификаторы

КодКогда срабатываетЧто делать
TDC190case — неизвестное преобразованиеupper, lower, capitalize, title
TDC191order не random и не sequentialДругих нет
TDC192Фильтр интерполяции неизвестенСм. Маски и регистр
TDC193${{Name}} или ${{Name.field}} называет необъявленноеОно попало бы в вывод буквально — проверяется вся ссылка, вместе с полем
TDC194У типизированного <data> нет nameКолонкой становится только именованный <data>
TDC195repeat не число и не диапазонrepeat="3" или repeat="1..5" (от 0 до 64)
TDC196repeat применён к <mix>Смесь выбирает одну ветку, а не производит список
TDC198separator без repeatОн склеивает повторы, значит они должны быть
TDC199Индекс в mask записан неверноИндексы с нуля, диапазон через ..x[0..3], w[-1]
TDC202flag задан, но ни один <case> не помечен anomaly="true"Колонка была бы сплошь отрицательной — пометьте ветку-выброс
TDC203flag на вложенном <mix>Колонку-ответ несёт только именованная смесь уровня <env>
TDC204repeat на генераторе, который не умеет повторятьсяТип назван в сообщении
TDC206each="" не называет последовательностьНазовите список, по которому идти
TDC207each называет последовательность с одним значениемНужен список — добавьте repeat источнику
TDC209Именованный <data> внутри строки с each=Такая строка даёт несколько строк, и имя колонки становится неоднозначным
TDC211weight применён к генератору, отличному от fileВеса берутся из колонки CSV
TDC212weight без columnВеса лежат во второй колонке, её надо назвать
TDC213weight вместе с orderorder идёт по строкам подряд, а взвешивание выбирает их по частоте

См. также