antlr/antlr4 · error · ArgumentException
missing start tag in pattern: {pattern}
Error message
missing start tag in pattern: {pattern} What it means
While splitting a pattern, the scanner found more stop delimiters than start delimiters — a '>' (or custom stop) that appears without a preceding unmatched '<'. Like the unterminated-tag case, escaped stops (default '\>') are not counted, so an escape-character mismatch between pattern and matcher configuration also triggers this.
Source
Thrown at runtime/CSharp/src/Tree/Pattern/ParseTreePatternMatcher.cs:638
}
else
{
p++;
}
}
}
}
}
// 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 chunksView on GitHub (pinned to 7d5770395b)
Solutions
- Balance the pattern: remove the stray '>' or add the missing '<'.
- Escape '>' that is meant as text: \>.
- Pick delimiters that never occur in the target text via SetDelimiters.
- Add a pre-compile lint for user patterns: unescaped starts must equal unescaped stops.
Example fix
// before
var p = parser.CompileParseTreePattern("List<int>> items", RULE_type, null);
// after
var p = parser.CompileParseTreePattern("List\<int\>\> items", RULE_type, null); // or use labels/tags for the type Defensive patterns
Strategy: validation
Validate before calling
int CountUnescaped(string s, char c) { int n = 0; for (int i = 0; i < s.Length; i++) { if (s[i] == '\\') i++; else if (s[i] == c) n++; } return n; }
if (CountUnescaped(pattern, '<') < CountUnescaped(pattern, '>')) throw new ArgumentException("missing start tag"); Try / catch
try { matcher.Compile(pattern); } catch (ArgumentException ex) when (ex.Message.Contains("missing start tag")) { /* remove or escape the stray '>' */ } Prevention
- Escape '>' meant as text (\>) — common when matching generics or comparisons.
- Consider custom delimiters via SetDelimiters if the target text is full of angle brackets.
When it happens
Trigger: Pattern strings like "ID> = 3" or "a > b" (comparison operators as plain text) passed to Compile; switching escape characters via SetDelimiters while patterns still use the old escape.
Common situations: Matching source that contains '>' as text (generics like List<int>, arrow operators); unbalanced quotes/delimiters from string concatenation bugs; patterns assembled from templates that drop an opening delimiter.
Related errors
- unterminated tag in pattern: {pattern}
- tag delimiters out of order 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/4dd5fc5bacf43807.
Report an issue: GitHub.