antlr/antlr4 · error · ArgumentException
tag delimiters out of order in pattern: {pattern}
Error message
tag delimiters out of order in pattern: {pattern} What it means
While splitting a pattern, the i-th start delimiter position is not before the i-th stop delimiter position (starts[i] >= stops[i]). This happens with interleaved delimiters such as '<a><b>' where scanning pairs them out of order relative to the collected indexes, or when a stop appears before its start in the string. The pattern's tag structure is malformed.
Source
Thrown at runtime/CSharp/src/Tree/Pattern/ParseTreePatternMatcher.cs:645
}
}
// System.out.println("");
// System.out.println(starts);
// System.out.println(stops);
if (starts.Count > stops.Count)
{
throw new ArgumentException("unterminated tag in pattern: " + pattern);
}
if (starts.Count < stops.Count)
{
throw new ArgumentException("missing start tag in pattern: " + pattern);
}
int ntags = starts.Count;
for (int i = 0; i < ntags; i++)
{
if (starts[i] >= stops[i])
{
throw new ArgumentException("tag delimiters out of order in pattern: " + pattern);
}
}
// collect into chunks now
if (ntags == 0)
{
string text = Sharpen.Runtime.Substring(pattern, 0, n);
chunks.Add(new TextChunk(text));
}
if (ntags > 0 && starts[0] > 0)
{
// copy text up to first tag into chunks
string text = Sharpen.Runtime.Substring(pattern, 0, starts[0]);
chunks.Add(new TextChunk(text));
}
for (int i_1 = 0; i_1 < ntags; i_1++)
{
// copy inside of <tag>
string tag = Sharpen.Runtime.Substring(pattern, starts[i_1] + start.Length, stops[i_1]);View on GitHub (pinned to 7d5770395b)
Solutions
- Rewrite the pattern so each '<' immediately precedes its matching '>' with no crossing pairs.
- Log the compiled starts/stops index lists (temporarily instrument the Chunkify/split path or count delimiters yourself) to see which pair is inverted.
- Build patterns from small validated fragments ('text', '<tag>') joined in order instead of raw string surgery.
Example fix
// before string pattern = fragA + "><" + fragB; // crossed delimiters var p = parser.CompileParseTreePattern(pattern, RULE_r, null); // after string pattern = fragA + "<" + tag + ">" + fragB; // well-formed tag
Defensive patterns
Strategy: validation
Validate before calling
// Verify each start precedes its paired stop before compiling
var starts = IndexesOfUnescaped(pattern, '<'); var stops = IndexesOfUnescaped(pattern, '>');
if (starts.Count == stops.Count)
for (int i = 0; i < starts.Count; i++)
if (starts[i] >= stops[i]) throw new ArgumentException($"tag delimiters crossed at {starts[i]}"); Try / catch
try { matcher.Compile(pattern); } catch (ArgumentException ex) when (ex.Message.Contains("out of order")) { /* rebuild the pattern from validated fragments */ } Prevention
- Assemble patterns from small validated fragments instead of raw concatenation.
- Test pattern builders with unit tests asserting well-formed delimiter pairs.
When it happens
Trigger: Patterns with crossed or nested-looking delimiters (e.g. "><", "<a> ><") where the k-th stop occurs at or before the k-th start; malformed concatenation producing delimiter sequences like '>...<'.
Common situations: Programmatic pattern assembly that concatenates fragments each carrying their own delimiters in the wrong order; hand-editing patterns and swapping halves; escaped delimiters making the effective order cross.
Related errors
- unterminated tag in pattern: {pattern}
- missing start tag in pattern: {pattern}
- pattern cannot be null
- start cannot be null or empty
- stop cannot be null or empty
AI-assisted analysis of antlr/antlr4@7d5770395b (2026-08-14).
Data as JSON: /api/errors/1cb337edc1f5ed9a.
Report an issue: GitHub.