antlr/antlr4 · error · ReferenceError

delegates

Error message

delegates

What it means

ProxyErrorListener is a fan-out error listener: it forwards every callback (syntaxError, reportAmbiguity, ...) to each listener in the delegates list. Its constructor raises ReferenceError('delegates') when delegates is None, mirroring the Java runtime's NullPointerException message. It is a plain constructor-contract check, not a parse-time failure.

Source

Thrown at runtime/Python3/src/antlr4/error/ErrorListener.py:55

    # This implementation prints messages to {@link System#err} containing the
    # values of {@code line}, {@code charPositionInLine}, and {@code msg} using
    # the following format.</p>
    #
    # <pre>
    # line <em>line</em>:<em>charPositionInLine</em> <em>msg</em>
    # </pre>
    #
    def syntaxError(self, recognizer, offendingSymbol, line, column, msg, e):
        print("line " + str(line) + ":" + str(column) + " " + msg, file=sys.stderr)

ConsoleErrorListener.INSTANCE = ConsoleErrorListener()

class ProxyErrorListener(ErrorListener):

    def __init__(self, delegates):
        super().__init__()
        if delegates is None:
            raise ReferenceError("delegates")
        self.delegates = delegates

    def syntaxError(self, recognizer, offendingSymbol, line, column, msg, e):
        for delegate in self.delegates:
            delegate.syntaxError(recognizer, offendingSymbol, line, column, msg, e)

    def reportAmbiguity(self, recognizer, dfa, startIndex, stopIndex, exact, ambigAlts, configs):
        for delegate in self.delegates:
            delegate.reportAmbiguity(recognizer, dfa, startIndex, stopIndex, exact, ambigAlts, configs)

    def reportAttemptingFullContext(self, recognizer, dfa, startIndex, stopIndex, conflictingAlts, configs):
        for delegate in self.delegates:
            delegate.reportAttemptingFullContext(recognizer, dfa, startIndex, stopIndex, conflictingAlts, configs)

    def reportContextSensitivity(self, recognizer, dfa, startIndex, stopIndex, prediction, configs):
        for delegate in self.delegates:
            delegate.reportContextSensitivity(recognizer, dfa, startIndex, stopIndex, prediction, configs)

View on GitHub (pinned to 7d5770395b)

Solutions

  1. Pass an iterable (possibly empty) list: ProxyErrorListener([]) is valid — only None is rejected.
  2. Default the parameter safely: def make_listener(extra=None): return ProxyErrorListener(extra or [ConsoleErrorListener.INSTANCE]).

Example fix

# before
listener = ProxyErrorListener(maybe_listeners)  # maybe_listeners is None -> ReferenceError

# after
listener = ProxyErrorListener(maybe_listeners or [])
Defensive patterns

Strategy: validation

Validate before calling

def proxy_listener(delegates=None):
    return ProxyErrorListener(delegates if delegates else [])

Type guard

def make_proxy(delegates):
    if delegates is None:
        delegates = []
    assert all(hasattr(d, 'syntaxError') for d in delegates)
    return ProxyErrorListener(delegates)

Prevention

When it happens

Trigger: ProxyErrorListener(None) or ProxyErrorListener(delegates) where delegates evaluated to None (e.g. a list built conditionally that ended up empty-None, or a typo'd variable).

Common situations: Custom multi-listener setups that aggregate console + logging listeners; passing a default argument that is None when no extra listeners were configured.

Related errors


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