{"record":{"id":"546f426ad2989b9d","repo":"antlr/antlr4","slug":"pattern-cannot-be-null-546f42","errorCode":null,"errorMessage":"pattern cannot be null","messagePattern":"pattern cannot be null","errorType":"validation","errorClass":"ArgumentException","httpStatus":null,"severity":"error","filePath":"runtime/CSharp/src/Tree/Pattern/ParseTreeMatch.cs","lineNumber":95,"sourceCode":"        /// is\n        /// <see langword=\"null\"/>\n        /// </exception>\n        /// <exception>\n        /// IllegalArgumentException\n        /// if\n        /// <paramref name=\"labels\"/>\n        /// is\n        /// <see langword=\"null\"/>\n        /// </exception>\n        public ParseTreeMatch(IParseTree tree, ParseTreePattern pattern, MultiMap<string, IParseTree> labels, IParseTree mismatchedNode)\n        {\n            if (tree == null)\n            {\n                throw new ArgumentException(\"tree cannot be null\");\n            }\n            if (pattern == null)\n            {\n                throw new ArgumentException(\"pattern cannot be null\");\n            }\n            if (labels == null)\n            {\n                throw new ArgumentException(\"labels cannot be null\");\n            }\n            this.tree = tree;\n            this.pattern = pattern;\n            this.labels = labels;\n            this.mismatchedNode = mismatchedNode;\n        }\n\n        /// <summary>\n        /// Get the last node associated with a specific\n        /// <paramref name=\"label\"/>\n        /// .\n        /// <p>For example, for pattern\n        /// <c>&lt;id:ID&gt;</c>\n        /// ,","sourceCodeStart":77,"sourceCodeEnd":113,"githubUrl":"https://github.com/antlr/antlr4/blob/7d5770395bb7b02eb56e7c62662cb1d7c08f42a3/runtime/CSharp/src/Tree/Pattern/ParseTreeMatch.cs#L77-L113","documentation":"ParseTreeMatch's constructor rejects a null ParseTreePattern. The match result must know which pattern produced it (Callers use Match.Pattern to inspect labels/tags), so a null pattern makes the object meaningless. Like the tree check, this fires only when code constructs ParseTreeMatch directly with a null pattern.","triggerScenarios":"new ParseTreeMatch(tree, null, labels, mismatchedNode); a custom matcher that forwards a pattern field which was never initialized (e.g. forgot to pass the pattern through the constructor of the subclass).","commonSituations":"Subclassing ParseTreePatternMatcher or ParseTreePattern and forgetting to propagate the pattern; refactoring that drops the pattern parameter; test scaffolding that stubs out pattern state.","solutions":["Obtain the pattern via parser.CompileParseTreePattern(patternText, patternRuleIndex) or the pattern variable already in scope and pass that.","Ensure custom matcher subclasses store and forward the ParseTreePattern they were constructed with.","Add a null check on the pattern before building the match result and fail with your own clearer error message."],"exampleFix":"// before\nvar m = new ParseTreeMatch(tree, null, labels, mismatch);\n\n// after\nvar pattern = parser.CompileParseTreePattern(\"<ID> = <expr>\", ParserRuleContext.EXPR);\nvar m = new ParseTreeMatch(tree, pattern, labels, mismatch);","handlingStrategy":"validation","validationCode":"if (pattern == null) throw new InvalidOperationException(\"pattern must be compiled first\");\nvar m = new ParseTreeMatch(tree, pattern, labels, mismatch);","typeGuard":"static bool HasPattern(ParseTreePattern p) => p != null;","tryCatchPattern":null,"preventionTips":["Always obtain patterns from CompileParseTreePattern and keep them non-null fields in matcher subclasses.","Pass the pattern parameter through in overrides instead of relying on fields."],"tags":["antlr","csharp","parse-tree-match","null-check","pattern"],"backgroundTag":null,"analyzedSha":"7d5770395bb7b02eb56e7c62662cb1d7c08f42a3","analyzedAt":"2026-08-14T14:47:56.354Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}