antlr/antlr4 · error · Exception
tree cannot be null
Error message
tree cannot be null
What it means
ParseTreeMatch is the result object returned by ParseTreePatternMatcher.match(); its constructor requires a non-None parse tree. 'tree cannot be null' fires when a None tree is supplied — normally internally by match(tree, pattern) when the caller passed None as the tree argument.
Source
Thrown at runtime/Python3/src/antlr4/tree/ParseTreeMatch.py:35
__slots__ = ('tree', 'pattern', 'labels', 'mismatchedNode')
#
# Constructs a new instance of {@link ParseTreeMatch} from the specified
# parse tree and pattern.
#
# @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 areView on GitHub (pinned to 7d5770395b)
Solutions
- Check the tree is not None before matching: if tree is not None: m = matcher.match(tree, pattern).
- For optional subrules, use a pattern that tolerates absence or check ctx.subrule_ctx is not None first.
- If you construct ParseTreeMatch by hand, validate all three required arguments (tree, pattern, labels).
Example fix
# before m = matcher.match(ctx.expr(), pattern) # expr() is None when the optional rule did not match # after expr = ctx.expr() m = matcher.match(expr, pattern) if expr is not None else None
Defensive patterns
Strategy: type-guard
Validate before calling
if tree is None:
raise ValueError('cannot pattern-match a None tree (optional subrule did not participate in the parse)')
result = matcher.match(tree, pattern) Type guard
def matchable(tree):
return tree is not None and hasattr(tree, 'accept') Prevention
- Check optional subrule getters (ctx.expr() etc.) for None before matching
- Validate tree, pattern, and labels together — the constructor rejects all three when None
When it happens
Trigger: Calling matcher.match(None, pattern) or ParseTreeMatch(None, pattern, labels, None); also constructing ParseTreeMatch directly with a None tree.
Common situations: Walking code that grabs ctx.child(i) or a labelled subtree that can be None (optional subrule not matched) and feeds it straight into pattern matching; refactoring that drops the tree variable.
Related errors
- pattern cannot be null
- delegates
- replace: range invalid: {}..{}(size={})
- replace op boundaries of {} overlap with previous {}
- insert op {} within boundaries of previous {}
AI-assisted analysis of antlr/antlr4@7d5770395b (2026-08-14).
Data as JSON: /api/errors/43f1a0a110367b28.
Report an issue: GitHub.