The tabnas error reference

46 error codes in three namespaces: 11 raised by the engine itself, 33 declared by individual grammar plugins, and 4 returned by the C shared libraries. A tabnas diagnostic always carries a code, and the code (never the message text) is what stays the same across the TypeScript and Go runtimes. Match on it.

Generated from the engine's schema/error-codes.json and from each plugin's tabnas.plugin.json descriptor: nothing on this page is hand-listed. Engine 0.12.9. Machine-readable: /versions.json.

Engine codes

Raised by the parsing engine itself, so any grammar can produce them. {placeholders} in a message are filled from the failing token and its details.

CodeMessage
cancel parse cancelled
end_of_source unexpected end of source
internal Go only internal error: {src}
invalid_ascii invalid ascii escape: {src}
invalid_unicode invalid unicode escape: {src}
unexpected unexpected character(s): {src}
unknown unknown error: {code}
unknown_rule unknown rule: {rulename}
unprintable unprintable character: {src}
unterminated_comment unterminated comment: {src}
unterminated_string unterminated string: {src}

Plugin codes

Declared by one grammar plugin, in its own error catalogue. A plugin raises these in addition to the engine codes above.

CodeDeclared by
bad_entity_ref @tabnas/xml
cdata_terminator_in_text @tabnas/xml
comment_double_dash @tabnas/xml
csv_extra_field @tabnas/csv
csv_missing_field @tabnas/csv
duplicate_attribute @tabnas/xml
duplicate_section @tabnas/ini
external_entity_in_attr @tabnas/xml
invalid_namespace_uri @tabnas/xml
invalid_xml_char @tabnas/xml
json5_empty @tabnas/json5
json5_no_value @tabnas/json5
lt_in_attr_value @tabnas/xml
multisource_cycle @tabnas/multisource
multisource_not_found @tabnas/multisource
pi_target_invalid @tabnas/xml
reserved_namespace @tabnas/xml
text_at_top_level @tabnas/xml
unbound_prefix @tabnas/xml
undeclared_entity @tabnas/xml
unparsed_entity_ref @tabnas/xml
unterminated_cdata @tabnas/xml
unterminated_comment @tabnas/xml
unterminated_doctype @tabnas/xml
unterminated_pi @tabnas/xml
unterminated_section @tabnas/ini
xml_invalid_tag @tabnas/xml
xml_mismatched_tag @tabnas/xml
zon_char @tabnas/zon
zon_doc_comment @tabnas/zon
zon_dup_field @tabnas/zon
zon_ident @tabnas/zon
zon_number @tabnas/zon

C ABI codes

A different namespace, and worth reading as one. These are not parse diagnostics: they come back in the JSON reply of a libtabnas<format> shared library, and they describe the call (a bad pointer, a handle you already freed) rather than the input you passed. All 28 libraries return the same four, because the ABI is uniform by decision (v1).

The distinction that actually costs people time: a library returns {"ok":true,"accept":false} when your input is outside the format. That is an answer, not an error, and it carries no code from this table. A code from this table means the call itself was wrong.

CodeReturned by
grammar every clib (28)
handle every clib (28)
internal every clib (28)
usage every clib (28)

Reading a diagnostic

Every failing parse produces the same structured object: the same fields in both runtimes, described by the engine's diagnostic.schema.json. The fields worth reading first are code (what went wrong), row/col (where), expected (which tokens would have matched) and ruleStack (how the parser got there).

The agents guide covers using these while iterating on a grammar, and the debug-parse skill is the same workflow packaged for an agent.