antlr/antlr4 · error · Exception

start cannot be null or empty

Error message

start cannot be null or empty

What it means

Thrown by ParseTreePatternMatcher.setDelimiters() in the Python3 runtime when the start delimiter is None or the empty string. The delimiters (default '<' and '>') mark token/rule tags like <ID> inside a tree pattern string, so an empty start delimiter makes tag splitting impossible. The API contract explicitly forbids null or empty delimiters.

Source

Thrown at runtime/Python3/src/antlr4/tree/ParseTreePatternMatcher.py:117

        self.lexer = lexer
        self.parser = parser
        self.start = "<"
        self.stop = ">"
        self.escape = "\\"  # e.g., \< and \> must escape BOTH!

    # Set the delimiters used for marking rule and token tags within concrete
    # syntax used by the tree pattern parser.
    #
    # @param start The start delimiter.
    # @param stop The stop delimiter.
    # @param escapeLeft The escape sequence to use for escaping a start or stop delimiter.
    #
    # @exception IllegalArgumentException if {@code start} is {@code null} or empty.
    # @exception IllegalArgumentException if {@code stop} is {@code null} or empty.
    #
    def setDelimiters(self, start:str, stop:str, escapeLeft:str):
        if start is None or len(start)==0:
            raise Exception("start cannot be null or empty")
        if stop is None or len(stop)==0:
            raise Exception("stop cannot be null or empty")
        self.start = start
        self.stop = stop
        self.escape = escapeLeft

    # Does {@code pattern} matched as rule {@code patternRuleIndex} match {@code tree}?#
    def matchesRuleIndex(self, tree:ParseTree, pattern:str, patternRuleIndex:int):
        p = self.compileTreePattern(pattern, patternRuleIndex)
        return self.matches(tree, p)

    # Does {@code pattern} matched as rule patternRuleIndex match tree? Pass in a
    #  compiled pattern instead of a string representation of a tree pattern.
    #
    def matchesPattern(self, tree:ParseTree, pattern:ParseTreePattern):
        mismatchedNode = self.matchImpl(tree, pattern.patternTree, dict())
        return mismatchedNode is None

View on GitHub (pinned to 7d5770395b)

Solutions

  1. Pass a non-empty string for start, e.g. setDelimiters('<<', '>>', '\\')
  2. Check delimiter values are non-empty before calling setDelimiters
  3. If you meant to match a literal '<' character, escape it with the escape delimiter instead of clearing the delimiters

Example fix

# before
matcher.setDelimiters('', '>', '\\')

# after
matcher.setDelimiters('<<', '>>', '\\')  # non-empty start and stop
Defensive patterns

Strategy: validation

Validate before calling

if not start:
    raise ValueError('start delimiter must be a non-empty string')
matcher.setDelimiters(start, stop, escape)

Type guard

def is_non_empty_str(s) -> bool:
    return isinstance(s, str) and len(s) > 0

Prevention

When it happens

Trigger: Calling matcher.setDelimiters('', '>', '\\') or setDelimiters(None, ...) to try to change tag syntax before compiling a pattern.

Common situations: Switching delimiters to allow literal '<' in matched text, or copying a delimiter string from config that arrived empty because of a typo or missing env var.

Related errors


AI-assisted analysis of antlr/antlr4@7d5770395b (2026-08-14). Data as JSON: /api/errors/ab8167f9de51fc30. Report an issue: GitHub.