antlr/antlr4 · error · Exception

labels cannot be null

Error message

labels cannot be null

What it means

Thrown by the ParseTreeMatch constructor in the Python3 runtime when the labels dict is None. ParseTreeMatch is the result object returned by ParseTreePattern.match() and records which pattern labels mapped to which parse-tree nodes. This error is a defensive precondition check; normal users get a ParseTreeMatch from the matcher and never construct one with None labels.

Source

Thrown at runtime/Python3/src/antlr4/tree/ParseTreeMatch.py:39

    #
    # @param tree The parse tree to match against the pattern.
    # @param pattern The parse tree pattern.
    # @param labels A mapping from label names to collections of
    # {@link ParseTree} objects located by the tree pattern matching process.
    # @param mismatchedNode The first node which failed to match the tree
    # pattern during the matching process.
    #
    # @exception IllegalArgumentException if {@code tree} is {@code null}
    # @exception IllegalArgumentException if {@code pattern} is {@code null}
    # @exception IllegalArgumentException if {@code labels} is {@code null}
    #
    def __init__(self, tree:ParseTree, pattern:ParseTreePattern, labels:dict, mismatchedNode:ParseTree):
        if tree is None:
            raise Exception("tree cannot be null")
        if pattern is None:
            raise Exception("pattern cannot be null")
        if labels is None:
            raise Exception("labels cannot be null")
        self.tree = tree
        self.pattern = pattern
        self.labels = labels
        self.mismatchedNode = mismatchedNode

    #
    # Get the last node associated with a specific {@code label}.
    #
    # <p>For example, for pattern {@code <id:ID>}, {@code get("id")} returns the
    # node matched for that {@code ID}. If more than one node
    # matched the specified label, only the last is returned. If there is
    # no node associated with the label, this returns {@code null}.</p>
    #
    # <p>Pattern tags like {@code <ID>} and {@code <expr>} without labels are
    # considered to be labeled with {@code ID} and {@code expr}, respectively.</p>
    #
    # @param label The label to check.
    #

View on GitHub (pinned to 7d5770395b)

Solutions

  1. Do not construct ParseTreeMatch yourself; call pattern.match(tree) which builds a valid labels dict internally
  2. If you must construct it, pass at minimum an empty dict {} instead of None
  3. Audit wrappers/subclasses for a labels argument that can be None and default it to {}

Example fix

# before
m = ParseTreeMatch(tree, pattern, None, mismatchNode)

# after
from antlr4.tree.ParseTreeMatch import ParseTreeMatch
m = ParseTreeMatch(tree, pattern, {}, mismatchNode)
Defensive patterns

Strategy: validation

Validate before calling

labels = labels if labels is not None else {}
m = ParseTreeMatch(tree, pattern, labels, mismatchedNode)

Type guard

def has_labels(labels) -> bool:
    return isinstance(labels, dict)

Prevention

When it happens

Trigger: Directly instantiating ParseTreeMatch(tree, pattern, None, mismatchedNode) from Python code, or a subclass/wrapper that passes an uninitialized labels dict. It cannot fire via ParseTreePattern.match(), which always builds the labels dict itself.

Common situations: Manually assembling a match result for unit tests, porting code from the Java runtime and forgetting that Python uses None checks, or partial initialization where labels was never populated.

Related errors


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