{"record":{"id":"f5e6cb6915be4b24","repo":"antlr/antlr4","slug":"target-cannot-be-null","errorCode":null,"errorMessage":"target cannot be null.","messagePattern":"target cannot be null\\.","errorType":"exception","errorClass":"NullPointerException","httpStatus":null,"severity":"error","filePath":"runtime/Java/src/org/antlr/v4/runtime/atn/Transition.java","lineNumber":78,"sourceCode":"\t\t\tput(EpsilonTransition.class, EPSILON);\n\t\t\tput(RangeTransition.class, RANGE);\n\t\t\tput(RuleTransition.class, RULE);\n\t\t\tput(PredicateTransition.class, PREDICATE);\n\t\t\tput(AtomTransition.class, ATOM);\n\t\t\tput(ActionTransition.class, ACTION);\n\t\t\tput(SetTransition.class, SET);\n\t\t\tput(NotSetTransition.class, NOT_SET);\n\t\t\tput(WildcardTransition.class, WILDCARD);\n\t\t\tput(PrecedencePredicateTransition.class, PRECEDENCE);\n\t\t}});\n\n\t/** The target of this transition. */\n\n\tpublic ATNState target;\n\n\tprotected Transition(ATNState target) {\n\t\tif (target == null) {\n\t\t\tthrow new NullPointerException(\"target cannot be null.\");\n\t\t}\n\n\t\tthis.target = target;\n\t}\n\n\tpublic abstract int getSerializationType();\n\n\t/**\n\t * Determines if the transition is an \"epsilon\" transition.\n\t *\n\t * <p>The default implementation returns {@code false}.</p>\n\t *\n\t * @return {@code true} if traversing this transition in the ATN does not\n\t * consume an input symbol; otherwise, {@code false} if traversing this\n\t * transition consumes (matches) an input symbol.\n\t */\n\tpublic boolean isEpsilon() {\n\t\treturn false;","sourceCodeStart":60,"sourceCodeEnd":96,"githubUrl":"https://github.com/antlr/antlr4/blob/7d5770395bb7b02eb56e7c62662cb1d7c08f42a3/runtime/Java/src/org/antlr/v4/runtime/atn/Transition.java#L60-L96","documentation":"Every Transition subclass validates in its constructor that the target ATNState is non-null and throws NullPointerException('target cannot be null.'). A transition without a target would make the ATN graph untraversable, so construction fails fast. This is almost always a programming error in code that builds ATNs by hand.","triggerScenarios":"new AtomTransition(null, label), new RuleTransition(ruleStart, ruleIndex, 0, null), new SetTransition(null, set), etc. Also any helper that passes a followState or target variable that was never initialized. Standard ANTLR tool/runtime code paths never pass null.","commonSituations":"Unit tests that stub ATN pieces. Custom ATN generators or grammar-transform tools. Refactorings where a state-creation function changed to return null on failure and callers still pass it straight into a transition constructor.","solutions":["Fix the caller to create the target state first (atn.newState(...) / newStateOfType) and add it via atn.addState before building transitions into it","Add null checks / Optional at the boundary that produces the state so failures surface at the real source","If writing tests, use ATN test fixtures from ANTLR's own test suite rather than null stubs"],"exampleFix":"// before\nATNState target = null; // forgot to create\natn.addEdge(src, new EpsilonTransition(target)); // NPE\n// after\nATNState target = atn.newState(); // e.g. BasicState\natn.addState(target);\natn.addEdge(src, new EpsilonTransition(target));","handlingStrategy":"validation","validationCode":"static ATNState requireState(ATNState s) {\n    if (s == null) throw new IllegalStateException(\"target state not created yet\");\n    return s;\n}\n// then: atn.addEdge(src, new EpsilonTransition(requireState(target)));","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Create and atn.addState() every state before any transition into it","Enable -Xlint and null annotations in custom ATN-building code","Fail fast on null where states are produced"],"tags":["antlr","java","atn","transition","null-pointer"],"backgroundTag":null,"analyzedSha":"7d5770395bb7b02eb56e7c62662cb1d7c08f42a3","analyzedAt":"2026-08-14T14:47:56.354Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}