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

Коды ошибок

Все диагностики, которые может выдать 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 членов), TDC299 (колонка uniq за 100 000 строк — её память растёт вместе с числом строк; во втором своём значении, пул объявлен не в том порядке, это ошибка), TDC251 (доля percent, просящая меньше одной строки), TDC272 (локаль, которая прекрасно даёт имена, но не везёт названий месяцев, — даты выйдут по-английски) и TDC284 (secret=, записанный в конфигурацию прямо текстом: ключ едет всюду, куда едет она сама) и TDC301 (список долей, оставляющий объявленное значение на 0%, так что выпасть оно уже не может). Каждое говорит об этом в своей строке ниже.

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

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

КодКогда срабатываетЧто делать
TDC001В файле нет корневого <tdc> или файл вообще не разобрался — синтаксическая ошибка, в том числе закрывающий тег с чужим именем (<sequence>…</gen>) или вложенность глубже 64 уровней, до которой не доходит ни одна живая конфигурация, а сгенерированная доходитОберните всё в один <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="[[%]]". Нет ни одной ("%%", "%x", % вовсе нет) — не подставится ничего; несколько ("[%]-[%]") — прочитается только правая, а остальные станут литеральным %, которого в вашем тексте нет. 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 оставляет ячейку пустой
TDC069timeout — не положительное число секундtimeout="30" ждёт ответа тридцать секунд; без него — 30 по умолчанию
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" или if="Seq == Value" со значением, которого последовательность не выдаёт; <case is="…"> или ключ <map> вне списка предмета; parent="Seq.Value" на значении, которого не бываетВетка мёртвая. Именно предупреждение: сузить список намеренно — нормальная практика
TDC217Путь шаблона существует, но не для локали прогонаСообщение называет локаль; поставьте local= на <gen> или <env>, либо выберите путь, который есть в вашей локали
TDC218uniq="true" на последовательности без своих значений — <compute> читает другие, if= выбирает ветку на строку, а running/stat/formula/смещение даты вычисляются, а не разыгрываютсяПоставьте 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Пул читает пул, объявленный ниже, или сам себяПулы строятся в порядке объявления, поэтому пул может читать только те пулы, что выше. Поднимите тот, который он читает. Из-за этого же порядка цикл между пулами записать нельзя
TDC241Два пула объявлены под одним именемПул берут по имени, поэтому двум одно имя не подходит. Раньше второй молча заменял первый, и единственным следом был TDC193 в блоке про поле, которого «нет»
TDC242anomaly или missing — не число в [0, 1]Оба задают ДОЛЮ значений: anomaly="0.05", missing="0.1"
TDC243anomaly на списке value, где нет ни одного числаАномалия умножает число, поэтому список слов вернётся неизменным
TDC246anomaly_flag на <gen> внутри <case>Тело ветки — это склейка частей, поэтому флаг на одной части не описывает строку: ставьте flag="ИМЯ" на сам <mix>
TDC247step у <gen type="date"> не является шагом, которым можно идти, либо смешивает календарную единицу с фиксированнойПишите 15m, 1h30m, 2d, 3mo, 1y — единицы s, m, h, d, w, mo, y; голое число означает дни
TDC248step без order="sequential" на том же <gen>Диапазон никто не обходит — даты по-прежнему берутся случайно. Добавьте order="sequential" или уберите step
TDC249weekdays называет несуществующий день неделиsun, mon, tue, wed, thu, fri, sat — диапазон mon..fri или перечисление sun,wed
TDC250weekdays при шаге в целое число недель или при календарном шагеДве причины под одним кодом. Целое число недель фиксирует день недели, поэтому фильтр совпал бы со всеми строками или ни с одной. Календарный шаг делает обратное — 1mo идёт четверг, воскресенье, воскресенье, среда, — поэтому какие строки уцелеют, решал бы календарь, а не конфиг
TDC252peak_at у <gen type="timeseries"> не числоpeak_at — это строка, на которой пикует сезонная волна, и считается она как period: peak_at="182" при period="365" ставит пик на первое июля
TDC253peak_at без period на том же <gen>У волны сначала должна быть длина, и только потом — высшая точка. Добавьте period или уберите peak_at
TDC251(предупреждение) Доля percent просит меньше одной целой строкиpercent — это точная квота по строкам, которые до неё доходят, поэтому 10 % от подмножества в пять строк просят половину записи. Половину записи выдать нельзя: ветка сработает один раз или ни разу, и решает это seed. Поднимите долю или count
TDC254Ход без шага: диапазонный repeat="2..5" рядом с order="sequential" или идущая по порядку date с любым repeat=Фиксированный repeat="4" работает — строка берёт с хода четыре значения. У диапазонного нет постоянного числа значений на строку, поэтому строка 5 начиналась бы там, где случайно закончили строки 0–4. А идущая по порядку дата несёт рядом с текстом момент времени, и у строки с несколькими датами нет одного момента, который можно отдать of= и plus=
TDC255decimals= вместе с include= или exclude=Уберите одно. Набор, собранный через include/exclude, состоит из целых, и выбор равномерен по ним — округлять нечего, движок молча выдавал целые
TDC256Маска без шаблона — <mask> без pattern= или ${{X|mask}} без аргументаЗадайте шаблон. Без него маска не оставляет ничего и возвращает пустую строку — колонка выходит пустой
TDC257Выражение if= вызывает функцию, которой нетЛибо опечатка — тогда рядом стоит близкое имя, — либо одна из sin, cos, exp, log и им подобных: у них ответ с причиной, потому что каждый язык считает их чуть по-разному, а сравнение превращает последний бит в другую строку. Сегодня есть: abs, ceil, floor, max, min, round, trunc
TDC258Функции в выражении if= дали не столько аргументовabs, ceil, floor, round и trunc берут ровно один; min и max — сколько дадите
TDC259Список […] стоит не справа от inСписок — это набор значений для проверки, поэтому он что-то значит только в виде Country in [US, CA, MX]. Сам по себе он не даёт условию никакого значения
TDC260В at() передан не списокСписок из repeat приходит в выражение склеенным текстом, поэтому at(Items, 1) просит второй элемент списка из одного и отвечает пустотой. Сначала разрежьте: at(split(Items, ","), 1)
TDC261В at() передан индекс, который индексом не являетсяИндекс — целое число, ноль или больше. За концом списка пусто намеренно: строки из repeat="1..4" разной длины. А -1, 1.5 и "one" — ошибки, и каждая из них раньше давала ту же пустую колонку
TDC262<gen type="stat"> не говорит, что считать (of=) или какую статистику (op=), либо называет несуществующуюСтатистика читает чужую колонку и ничего не тянет сама, поэтому нужны оба. op= — одно из sum, mean, median, min, max, count, stddev; decimals= — от 0 до 10
TDC263${{Name}} в атрибуте, который его не раскрываетИнтерполяция доходит до текста внутри <data> и до <gen type="template" value=>, и больше никуда — везде ещё скобки остаются буквальными символами. Чтобы одна колонка зависела от другой, прочтите её в условии if= или соберите значение в <compute>
TDC264<gen type="date" of="…"> записан неверноСмещению нужен plus= (7d, 3..10d, 1..3mo, -10..-3d), меньшая граница пишется первой, единицы те же, что у step=. Атрибуты, задающие СОБСТВЕННЫЙ жребий генератора — value, from, to, range, oldest, youngest, order, step — ничего не значат, когда of= уже поставил дату относительно другой колонки, поэтому они отвергаются, а не игнорируются. Зеркальный случай тоже отвергается: plus= у даты без of= не от чего отмерять
TDC265У <assert> нет условияУтверждение — единственная конструкция, вся ценность которой в том, что оно ПАДАЕТ, а без that= оно не может упасть никогда. Опишите свойство, которым запуск обязан обладать, на языке if=, над колонками, одинаковыми для всего запуска
TDC266У <assert> нет сообщенияsays= — это то, что читатель увидит месяцы спустя в CI-логе. Одно выражение оставляет ему самому догадываться, что оно защищало
TDC267(второе значение) uniq="true" на <sequence>, внутри которой <distinct><distinct> чинит одну запись, чтобы её поля различались; uniq затем перетасовывает готовые колонки и не знает, какие пары были запрещены, — починка отменяется. Оставьте что-то одно — или дайте каждому полю свою <sequence>, оберните их в <uniq>, а <distinct> поставьте на уровне env
TDC267uniq="true" вместе с mask=, case=, missing=, repeat=, separator= или anomaly=Выбор без возвращения строит колонку напрямую и не доходит до слоя, который переписывает значения, — атрибут мог только пропасть. Применить его значило бы сломать другое обещание: маска сводит два разных значения к одним и тем же символам
TDC268if= на <gen type="pool">Ссылка публикует целую ЗАПИСЬ, а <gen> с if= становится условной веткой, которую резолвер пула не узнаёт, — ни одна колонка Ref.field не регистрировалась, и ${{Ref.name}} попадал в вывод собственным текстом. Чтобы оставить строки без записи, используйте parent=
TDC269if= на <gen> внутри <case>Тело ветки — это несколько частей, склеенных в одно значение, поэтому у условия на одной части нет значения, к которому откатиться. Раньше атрибут принимался и игнорировался, и часть появлялась на каждой строке — включая те, которые условие исключало. Ставьте условие на ветку: <case if="…">
TDC270В <tdc> второй <env> или <block>Оба читаются как ПЕРВЫЙ в своём роде, поэтому второй выбрасывается целиком — вместе со всеми объявленными в нём последовательностями и строками, — а прогон завершается как ни в чём не бывало. Ошибка ставится на втором
TDC271percent= рядом с order="sequential"Обход списка по порядку жёстко задаёт, какое значение достанется строке, — распределять доли уже негде. Проценты принимались и выбрасывались: percent="98,1,1" на сотне строк давал 34 / 33 / 33
TDC272(предупреждение) <env local=…> называет локаль без переводов датЛокаль — хороший источник ИМЁН, но названий месяцев не содержит, поэтому даты выйдут по-английски. На <gen type="date" local=…> это отвергается (TDC153), а здесь до сих пор молчало. Срабатывает только если формат читает локаль: format="YYYY-MM-DD" одинаков на всех языках
TDC273аргумент фильтра, которым фильтр не может воспользоватьсяslice:5,2 кончается раньше, чем начинается, и опустошает колонку; slice:abc, group:abc, group:0, compact:1 и compact:99 оставляют значение нетронутым. group и compact БЕЗ аргумента сохраняют документированные значения по умолчанию (3, основание 36)
TDC274аргумент у фильтра, который его не читаетtrim, sql, upper, lower, capitalize и title — целые преобразования; ${{X|trim:junk}} молча игнорировал junk. Соединяйте цепочкой: ${{X|trim|upper}}
TDC275replace, которому нечего искать${{X|replace}} и ${{X|replace:,to}} не меняют вообще ничего. Пишите обе части: ${{X|replace:from,to}}
TDC276зафиксированный параметр пакета не той длиныУ идентификатора с контрольной цифрой жёсткая раскладка, поэтому часть другой длины её ломает, а не сдвигает. usa.finance.aba_routing prefix="12345" ронял запуск; tail="678" писал шестизначное «не число». Сообщается только там, где длину можно ДОКАЗАТЬ по телу самого пакета
TDC277decimals=, которому нечего округлятьБез value= генератор выдаёт строку ЦИФР — идентификатор, — и округлять там нечего. <gen type="number" length="4" decimals="2"/> выдавал 4566, 5773, 5192
TDC278decimals= рядом с length=У дробного значения нет целой ширины, до которой можно дополнить, поэтому отбрасывался как раз length=: value="1..9" length="3" decimals="2" выдавал 3.78, 2.89
TDC279first_zero="false", который диапазон не может выполнитьЛюбое значение из 0..5 — одна цифра, поэтому трёхзначная запись всегда дополняется нулями. Генератор перебрасывал по сто раз на строку и всё равно выдавал запрещённую форму: 005, 002, 003. Сообщается только там, где это ДОКАЗУЕМО по диапазону
TDC280две записи одного диапазона датvalue=, пара from/to и range= говорят одно и то же, а генератор читает их в этом порядке и останавливается. value="2020-05-05" from="1990-01-01" to="1990-12-31" выдавал 1990-05-11 и молча выбрасывал остальное. value="today", "now" и "birth" — тоже записи диапазона
TDC281диапазон дат кончается раньше, чем начинаетсяРозыгрыш брал минимум и максимум двух концов, поэтому from="2020-01-01" to="2010-01-01" выдавал вполне правдоподобные даты из диапазона, которого никто не писал. plus="10..3d" отвергается как опечатка, а не меняется местами, с самого начала; здесь та же опечатка
TDC282order="sequential" только у части участников связки row=Либо поставьте order="sequential" всем участникам, либо снимите — в смешанной связке они перестают читать одну строку на запись
TDC283anomaly_flag у <gen>, который лишь одна из частей своей <sequence>Флаг отмечает, В КАКИХ СТРОКАХ появился выброс, а последовательности, собранной из нескольких частей — второго <gen>, литерала <data> или name=, который делает этот <gen> полем, — некуда положить такую колонку. Вынесите <gen> в отдельную <sequence>: заодно получите и само значение отдельной колонкой. Та же причина, что у TDC246, только уровнем выше
TDC284(предупреждение) secret= записан прямо в конфигурацию, либо пустКлюч внутри конфигурации едет всюду, куда едет она сама, — в систему контроля версий в том числе. secret="env:TDC_HTTP_SECRET" читает его из окружения, secret="file:~/.tdc/service.key" — из файла, которого нет в репозитории. Литерал даёт ПРЕДУПРЕЖДЕНИЕ: сервис на 127.0.0.1 на один вечер — вполне живой случай; secret="" — ошибка, потому что подпись без ключа подделает кто угодно
TDC285Значение атрибута рисунка — не одно из его слов и не числоmode=, interp=, spread= и decimals= читались только во время прогона, поэтому check называл mode="banana" годным, а прогон отказывал — единственное место, где check не отвечал на вопрос «запустится ли это». Допустимо: `mode="signal
TDC286<is_digit> или <encode> получил <field name="_count"> или <field name="_total">Эти два поля приходят ЧИСЛАМИ, а обоим тегам нужен один символ текста. <is_digit> отвечал «нет» на каждой строке — включая строки, где счётчик и есть одна цифра, — и check молчал; <encode> обрывал прогон сообщением «expected a single-character string» без файла и строки, на конфиге, который check тоже назвал годным. Сравнивайте само число через <equals> или <less_than>, для <encode> оберните в <concat>, либо кладите нужный символ в <str>
TDC287<equals>, <greater_than> или <less_than> получил литерал <str>, который не числоВсе три сравнения работают с числами. Строка из цифр читается как число, которое она пишет — <equals><str v="7"/><int v="7"/></equals> истинно, — поэтому отказ приходит только на литерал, который числом не является. Раньше такой обрывал прогон сообщением «expected an integer in <equals>, got the string …» без файла и строки, на конфиге, который check назвал годным. Проверяются только литералы: что окажется в <field>, до прогона неизвестно
TDC288<var> — тег переименован в <use>Он никогда ничего не объявлял: <let> связывает имя, а этот читает его обратно — о чём новое имя и говорит. Без отдельного отказа старое написание проваливалось в «неизвестный тег compute», а это сообщает, что написано неверно, но не что писать. Атрибут name= не изменился
TDC289distinct= получил не true и не falseУ атрибута два написания и никакого третьего смысла. Считать незнакомое слово за false — значит оставить конфиг, который просит разные значения и молча получает повторы
TDC290distinct= без repeat=Одно значение не может повториться само с собой, поэтому атрибут был бы прочитан и ничего не сделал. Добавьте repeat="N" или repeat="A..B", либо уберите distinct=
TDC291percent= и distinct= на одном <gen>percent= обещает точные доли на весь прогон; distinct= меняет это обещание на гарантию внутри строки. Оба сразу не держатся, поэтому ни одно не отбрасывается молча. Доли по ДЛИНАМ списков ставьте на <mix> или <switch> снаружи, а repeat= — на <gen> внутри
TDC292repeat= под distinct= просит больше значений, чем есть в спискеИз пяти значений не выйдет шесть разных. Сообщается до запуска, если пул виден в конфиге (type="text", целочисленный диапазон, односимвольный набор symbol); на запуске, если не виден (файл пакета, колонка CSV, regex) — они читаются только во время генерации
TDC293<gen type="pattern"> без y_range=У рисунка нет собственного масштаба — одна и та же кривая выходит из одного редактора в координатах 0..100, из другого 0..10002345345. y_range="min..max" говорит, что эти координаты значат: он становится полом и потолком холста рисунка. Без него любой ответ был бы догадкой о чужих настройках экспорта, поэтому атрибут обязателен, а не подразумевается
TDC294<gen type="formula"> без expr=, либо expr=, который не разбирается, либо decimals= вне 0..10Формула И ЕСТЬ своё выражение, так что без него вычислять нечего. Выражение — тот же язык, что у if=, см. Выражения. Имя внутри него, не являющееся колонкой, объявленной выше, даёт TDC240 — тот же код, что у running и stat на то же правило
TDC295if= на колонке running, stat, formula или смещении датыОни строятся один раз, на весь прогон, в порядке объявления — а if= просит значение, выбираемое построчно; одновременно верным быть не может. Ставьте условие туда, где значение ИСПОЛЬЗУЕТСЯ (<data if="…">), либо считайте колонку безусловно и ветвитесь по ней потом
TDC296Колонка running, stat, formula, дата от другой даты или <compute> внутри <uniq> или <distinct>Группа ПЕРЕСТАВЛЯЕТ готовые колонки, пока записи не станут уникальными. Разыгранное значение означает одно и то же, куда бы ни попало; вычисленное описывает ту строку, для которой посчитано, — переставили, и арифметика стала неверной. Оберните группой те колонки, которые эта читает, а вычисленную оставьте снаружи: она пойдёт за тем, что расставит группа
TDC297Два способа читать один файл сразу — read="quantile" рядом с weight=, row= или order="sequential"; опечатка в read=; sample= без негоweight= держит доли во второй колонке, row= связывает несколько колонок с одной СТРОКОЙ файла, order="sequential" идёт по списку по порядку, а read="quantile" говорит, что значения И ЕСТЬ распределение и строка попадает в любую точку отсортированной выборки. Оставьте одно чтение: считаемому нужен weight= с его точной квотой, измеряемому — квантильное
TDC298Один ключ row= над двумя разными файламиСвязка — это одна СТРОКА одного файла, поэтому строки, принадлежащей обоим, не существует. Направьте всех участников связки на один src= или дайте этому свой ключ row=
TDC299(предупреждение) uniq="true" более чем на 100 000 строкОбещание про готовую колонку стоит памяти, которая растёт вместе с count, — на любом движке: цена принадлежит обещанию, а не какому-то одному из них. Около 250 байт на значение, измерено: 2 000 000 строк стоят примерно 477 МБ, а составной uniq — ещё больше. Одиночная выбираемая колонка платит дважды: выбор без возврата нельзя сделать построчно, поэтому она вдобавок идёт в памяти, что бы ни просил mode=. Работает; просто стоит делать это осознанно
TDC300fit=, который не полоса, идёт на убывание или стоит рядом с points=/upper=/lower=fit="низ..верх" говорит, во что превращаются собственные нижняя и верхняя точки рисунка на оси значений, — так кривая из src= получает своё место, ведь файл несёт форму и не несёт единиц. Два числа, меньшее первым; перевернуть рисунок вверх ногами — это другая просьба. Рядом с набранными точками атрибут отклоняется: 80 там уже означает 80% от y_range, и размещать больше нечего. Уберите его — и рисунок займёт весь y_range
TDC301(предупреждение) Список долей оставляет объявленное значение с 0%percent короче value — это нормально: остаток достаётся тем позициям, которые вы не написали, поэтому value="a,b,c" percent="30,40" отдаёт c оставшиеся 30. Но когда написанные доли уже дают 100, остатка нет, и значение объявлено, а выпасть не может: percent="50,50" на 300 строках дал 150 a, 150 b и ни одного c. Ноль, написанный вами самими — percent="50,0,50" — принимается как есть и молчит
TDC302<distinct> или <uniq> над ссылками <gen type="pool"> в форме, которая ничего не значит: ссылка рядом с обычной последовательностью, ссылки на два разных пула, ссылок больше, чем записей в пулеГруппа над ссылками сравнивает, КАКУЮ ЗАПИСЬ взяла строка, — значит, сравнивать должно быть что, и записей должно хватать. Все три формы раньше принимались и не делали ничего
TDC303missing_when=, который ничего не решает: без условия, без доли missing= рядом или на ячейке с repeat=Условие и называет механизм — missing_when="Age < 30" это MAR, missing_when="_value > 150000" это MNAR, — поэтому написанное и пустое это вопрос, который не договорили, а без доли ему нечего включать. В повторяющейся ячейке на одной строке несколько значений, а условие спрашивает про одно; вместо того чтобы гадать, что имелось в виду, сочетание отклоняется. Все три раньше молча принимались и не делали ничего
TDC304Сезонные списки не сходятся: в amplitude= или peak_at= записей не столько, сколько в period=, либо среди нескольких периодов стоит 0period="7,365" amplitude="120,400" peak_at="5,182" описывает одни и те же две волны трижды, позиция в позицию, поэтому несовпадающая длина не описывает никакой волны — лишнюю запись раньше просто отбрасывали молча. Единственное сокращение — одна amplitude на волны равной высоты. period="0" сам по себе значит «нет сезонной волны»; среди нескольких это волна без длины рядом с волнами, у которых длина есть
TDC305noise_correlation=, который нельзя выполнить: вне −1..1 или без noise= рядомЭто доля дрожания одной строки, переходящая в следующую. На единице ряд ушёл бы и не вернулся — это случайное блуждание, а не шум, — а выше единицы он растёт без границы; и то и другое отклоняется, а не зажимается. Без noise= коррелировать нечего, и атрибут ничего не решает
TDC306<assert>, на котором написаны и that=, и each=Они отвечают на разные вопросы и проверяются разное число раз: that= — один раз, по значениям за весь запуск, each= — на каждой строке. Один тег с обоими не даёт читателю понять, которое из двух описывает фраза в says=. Напишите два утверждения, каждое со своим says=, чтобы отказ говорил, которое из них сломалось
TDC307distinct="true" рядом с order="sequential"distinct= берёт значения строки без возврата, а идущая по порядку строка ничего не тянет — её значения решает позиция. Выполнить и то и другое невозможно, а тихо проигнорировать одно — это как раз то, из-за чего конфиг начинает утверждать то, чего у него никогда не было
TDC308Условие на <gen>if= или missing_when= — называет колонку, объявленную нижеУсловие вычисляется, пока эта колонка строится, поэтому колонки, стоящей ниже, ещё не существует. Два движка отвечали на это по-разному, и оба ответа были разумны: движок в памяти читал её как пустую, и условие не срабатывало никогда, а потоковый строил колонку по требованию, и условие срабатывало по-настоящему. Перенесите названную <sequence> выше этой. Условие, которое читается уже после того, как строка собрана — <data if=>, <line if=>, <assert that=> — может называть любую колонку
TDC244type="pattern" без points, src или upperРисунку нужна форма, откуда читать: points="0,0 1,5 2,3", файл в src или upper/lower для полосы

Три номера в этом диапазоне были зарезервированы, пока проектировались пулы, и останутся неиспользованными — пропуски объявлены, а не оставлены молча:

  • TDC227filter=, называющий несуществующую колонку. Голое слово в языке выражений всегда было строковым литералом — именно так filter="clinic == North" говорит «только северные». Опечатка и литерал записываются одинаково, поэтому проверка ставила бы ошибку на рабочих конфигурациях. Там, где литерал — заведомая ошибка (ни один участник не может держать это значение), об этом говорит TDC225, и без догадок.
  • TDC228${{Пул.поле}}, обращающееся к пулу мимо ссылки. TDC193 уже сообщает об этом как об имени, которое ни во что не разрешается, а второй код на ту же фразу не стоит номера.
  • TDC233 — ни один кандидат не прошёл filter= на строке N, для выражений сложнее простого равенства. Такой отказ бывает и он нужен; просто он не диагностический код. Сравнение идёт со значением, которое появляется только когда строка уже строится, — значит, это дело прогона, и сообщение прогона называет строку и значение, которому никто не подошёл.

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

См. 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<use name="X"> не связан ни с одним <let>Оберните в <let name="X">…</let> или исправьте имя
TDC183У compute-операции ровно на два операнда другое число детейБинарны только <divide> и <mod> — третий операнд там не значит ничего. <add>, <subtract> и <multiply> вариадические: <add> по трём операндам складывает все три, а без операндов даёт 0 (<multiply>1)
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>, <switch> — вложенный <switch> внутри ветки полноправен (см. TDC245)
TDC131Внутри фикстуры тег, который она не принимает, либо <data> без обёртки <line>Тело фикстуры состоит из <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 называет локаль без данных о датахВстроено двадцать четыре: ar, cs, de, el, en, es, fi, fr, hi, hu, id, it, ja, ko, nl, pl, pt, ru, sv, th, tr, uk, vi, zh-cn. Девятнадцать отзываются ещё и на трёхбуквенный псевдоним (ara, ces, deu, ell, eng, spa, fin, fra, hun, ind, ita, jpn, kor, nld, pol, por, tur, ukr, vie); у hi, ru, sv, th, 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}} называет необъявленноеОно попало бы в вывод буквально — проверяется вся ссылка, вместе с полем
TDC193(второе значение) anomaly_flag= на <gen>, где нет anomaly=Колонка-флаг отмечает строки, сделанные выбросами, а выбросов никто не делал. Добавьте anomaly="p" или уберите флаг
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 идёт по строкам подряд, а взвешивание выбирает их по частоте

См. также