Коды ошибок
Все диагностики, которые может выдать TDC, по кодам. Загляните сюда, когда запуск остановился, а одного сообщения не хватило.
Как читать диагностику
В диагностике четыре части, и код — та из них, что не меняется между версиями:
формулировку могут улучшить, TDC193 останется TDC193.
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 | У тега атрибут, который движок не читает | Прогон останавливается: конфиг просил то, чего не получил бы. Проверьте написание — в сообщении есть подсказка с ближайшим настоящим именем |
TDC020 | count не целое неотрицательное | count="1000" |
TDC021 | В шаблоне inject нет места под % | Маркеру нужен % под имя, например inject="[[%]]" |
Последовательности
| Код | Когда срабатывает | Что делать |
|---|---|---|
TDC030 | У тега, которому нужно имя, его нет | Добавьте name="…" |
TDC031 | Имя последовательности начинается с _ | Этот префикс отдан встроенным |
TDC032 | Две последовательности с одним именем | Переименуйте одну — ссылка была бы неоднозначной |
TDC033 | Имя совпало со встроенным | Возьмите другое: встроенное всегда выигрывает |
TDC034 | Значение parent не в форме Родитель.Значение | Пишите обе части, например parent="Gender.Male" |
TDC035 | Родительская последовательность объявлена после этой | Поднимите родителя выше — разбор идёт сверху вниз |
TDC214 | parent= называет составную последовательность | Родитель отбирается по значению, а группа полей своего значения не даёт |
TDC036 | Внутри <sequence> нет <gen> | Без генератора последовательность ничего не производит |
TDC110 | выведен из обращения — безымянный <gen> рядом с именованным теперь собирает значение, а не считается ошибкой | — |
TDC111 | Два поля одной составной последовательности с одним именем | Переименуйте одно |
TDC129 | <sequence> внутри тега уровня конфига не даёт там ничего пригодного | См. Последовательности |
Генераторы
| Код | Когда срабатывает | Что делать |
|---|---|---|
TDC040 | У <gen> нет type | Добавьте type="…" — см. Генераторы |
TDC041 | Тип неизвестен или не поддержан для встроенного <gen> | Проверьте написание — TDC подскажет ближайшее имя |
TDC050 | type="text" без value | Задайте список, например value="a,b,c" |
TDC051 | В percent больше значений, чем в списке value | По одному проценту на значение |
TDC052 | Элемент percent — не неотрицательное число | Заполненные позиции — числа; пустая делит остаток поровну |
TDC053 | Значения percent не дают в сумме 100 | Приведите к сумме 100 или оставьте позицию пустой под остаток |
TDC060 | type="file" без src | Укажите файл в src |
TDC061 | Файл не читается | Проверьте путь — он отсчитывается от конфига, либо используйте --data-path |
TDC062 | column не разрешается | Имя из заголовка (column="email") или номер с единицы (column="2") |
TDC064 | row без column | Связке строк нужно знать, из какой колонки CSV тянуть |
TDC065 | type="http" без src | Укажите адрес сервиса — src="http://127.0.0.1:5566/gen" |
TDC066 | src — не http(s)-адрес | Пишите http://… или https://…, с хостом и путём |
TDC067 | in= называет то, что не объявлено выше | Значение на строку берётся из более ранней <sequence> |
TDC068 | on_error не fail и не empty | fail (по умолчанию) роняет прогон; empty оставляет ячейку пустой |
TDC070 | type="template" без value | Задайте адрес через точку, например value="person.lastName" |
TDC071 | Адрес шаблона неизвестен | Проверьте написание или поставьте пакет, который его даёт |
TDC072 | value="date.range" без range, или параметр type="template", которого пакет не объявляет | Добавьте range="…"; либо проверьте имя параметра — сообщение перечисляет допустимые |
TDC073 | Устаревший range — не две корректные даты | Формат YYYY.MM.DD - YYYY.MM.DD |
TDC081 | Числовой диапазон записан неверно | value="10..99" |
TDC082 | first_zero не true и не false | Других значений нет |
TDC083 | length не число, не диапазон и не список через запятую | Например length="8", length="6..9", length="4,6,8" |
TDC084 | В percent на числовом value больше значений, чем допускает диапазон | По одному проценту на значение |
TDC085 | Элемент percent на числе — не неотрицательное число | Заполненные позиции — числа |
TDC086 | percent на числе не даёт в сумме 100 | Приведите значения к сумме 100 |
TDC087 | include/exclude без числового диапазона в value | Они фильтруют диапазон, значит он должен быть |
TDC088 | distribution вместе с несовместимым атрибутом | Именованное распределение само задаёт розыгрыш |
TDC089 | Параметры распределения неверны | См. Распределения |
TDC090 | Атрибут, который обязан быть числом, им не является | Проверьте значение |
TDC095 | type="regex" без value | Шаблон кладётся в value |
TDC096 | regex_max_length не положительное целое | Например regex_max_length="64" |
TDC097 | Регулярка не разбирается | Почините шаблон — дальше идёт сообщение самого парсера |
TDC098 | У type="symbol" заданы и value, и alphabet, либо ни один | Задайте ровно один — набор в value или именованный alphabet |
TDC099 | Именованный алфавит неизвестен | См. Символы |
TDC128 | type="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>, либо выберите путь, который есть в вашей локали |
TDC218 | uniq="true" на последовательности без своих значений — <compute> читает другие, if= выбирает ветку на строку | Поставьте uniq= на те последовательности, которые она читает, либо оберните их в <uniq> |
TDC219 | <compute> и <gen> в одной <sequence> — один из двух был бы выброшен | Вынесите <compute> в свою <sequence> и читайте разыгранную через <field> |
TDC220 | uniq="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> |
TDC225 | filter="field == X", где обе стороны не могут совпасть ни на одном значении | Оба списка написаны в конфиге, и они не пересекаются — значит каждая строка сужается до пустоты. Сообщение называет оба. Здесь докладывается только заведомое противоречие; редкое значение отвергается на той строке, где выпало |
TDC226 | filter= читает 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 в блоке про поле, которого «нет» |
TDC242 | anomaly или missing — не число в [0, 1] | Оба задают ДОЛЮ значений: anomaly="0.05", missing="0.1" |
TDC243 | anomaly на списке value, где нет ни одного числа | Аномалия умножает число, поэтому список слов вернётся неизменным |
TDC244 | type="pattern" без points, src или upper | Рисунку нужна форма, откуда читать: points="0,0 1,5 2,3", файл в src или upper/lower для полосы |
Нарастающие итоги
См. accumulate=
и <gen type="running">.
| Код | Когда срабатывает | Как исправить |
|---|---|---|
TDC237 | accumulate= на генераторе без repeat= | Накапливать нечего — списка нет. Добавьте repeat="N" или уберите accumulate=. (type="running" исключение: он накапливает по колонке) |
TDC238 | accumulate= называет несуществующую операцию | Одна из sum, min, max |
TDC239 | <gen type="running"> не говорит, что (of=) или как (accumulate=) накапливать | Нарастающий итог читает чужую колонку и сам ничего не разыгрывает, поэтому обязательны оба |
TDC240 | of= или 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> — не неотрицательное число | Заполненные позиции — числа |
TDC123 | percent на <mix>/<switch> не даёт в сумме 100 | Приведите значения к сумме 100 |
TDC124 | У <mix> ребёнок, отличный от <case> | Там может стоять только <case> |
TDC125 | У <case> неизвестный ребёнок | Разрешены <data>, <gen>, <mix> |
TDC131 | Внутри фикстуры вложен тег, который фикстуры не принимают | Фикстуры держат только <line> и <data> |
TDC132 | Внутри <line> стоит тег, которому там не место | Блок вывода — про раскладку, генераторы живут в <env> |
TDC133 | У <switch> нет on | Назовите последовательность, по которой идёт разбор |
TDC134 | on называет несуществующую последовательность или её поле | Проверьте имя — сообщение скажет, какая половина неверна |
TDC135 | У <switch> нет записей | Добавьте <map>, <case> или <default> |
TDC136 | (предупреждение) Строка <map> не в форме КЛЮЧ:ЗНАЧЕНИЕ — плохая строка пропускается, а остальная карта продолжает действовать | По одной паре на запись, через двоеточие |
TDC137 | У <case> внутри <switch> нет is | is — это ключ ветки |
TDC245 | name у <switch>, записанного внутри <case> | Вложенная форма даёт значение этой ветке; колонкой становится только <switch> уровня <env> |
Даты
| Код | Когда срабатывает | Что делать |
|---|---|---|
TDC150 | Задано только одно из from / to | Либо обе границы, либо ни одной |
TDC151 | Значение даты не разбирается | value="2020-01-01..2025-12-31", "birth", "today", "now" |
TDC152 | Маркер в format неизвестен | См. таблицу маркеров |
TDC153 | local называет локаль без данных о датах | Встроены: en, es, ru, zh-cn |
TDC154 | precision — не поддержанный шаг | См. precision |
Во время генерации
Эти возникают уже при генерации, а не при проверке: конфиг корректен, но сочетание выполнить нельзя.
| Код | Когда срабатывает | Что делать |
|---|---|---|
TDC160 | row="…" на встроенном <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> просто некуда положить.
Форматирование и модификаторы
| Код | Когда срабатывает | Что делать |
|---|---|---|
TDC190 | case — неизвестное преобразование | upper, lower, capitalize, title |
TDC191 | order не random и не sequential | Других нет |
TDC192 | Фильтр интерполяции неизвестен | См. Маски и регистр |
TDC193 | ${{Name}} или ${{Name.field}} называет необъявленное | Оно попало бы в вывод буквально — проверяется вся ссылка, вместе с полем |
TDC194 | У типизированного <data> нет name | Колонкой становится только именованный <data> |
TDC195 | repeat не число и не диапазон | repeat="3" или repeat="1..5" (от 0 до 64) |
TDC196 | repeat применён к <mix> | Смесь выбирает одну ветку, а не производит список |
TDC198 | separator без repeat | Он склеивает повторы, значит они должны быть |
TDC199 | Индекс в mask записан неверно | Индексы с нуля, диапазон через .. — x[0..3], w[-1] |
TDC202 | flag задан, но ни один <case> не помечен anomaly="true" | Колонка была бы сплошь отрицательной — пометьте ветку-выброс |
TDC203 | flag на вложенном <mix> | Колонку-ответ несёт только именованная смесь уровня <env> |
TDC204 | repeat на генераторе, который не умеет повторяться | Тип назван в сообщении |
TDC206 | each="" не называет последовательность | Назовите список, по которому идти |
TDC207 | each называет последовательность с одним значением | Нужен список — добавьте repeat источнику |
TDC209 | Именованный <data> внутри строки с each= | Такая строка даёт несколько строк, и имя колонки становится неоднозначным |
TDC211 | weight применён к генератору, отличному от file | Веса берутся из колонки CSV |
TDC212 | weight без column | Веса лежат во второй колонке, её надо назвать |
TDC213 | weight вместе с order | order идёт по строкам подряд, а взвешивание выбирает их по частоте |