{"record":{"id":"589e213980072213","repo":"antlr/antlr4","slug":"stop-cannot-be-null-or-empty-589e21","errorCode":null,"errorMessage":"stop cannot be null or empty","messagePattern":"stop cannot be null or empty","errorType":"validation","errorClass":"ArgumentException","httpStatus":null,"severity":"error","filePath":"runtime/CSharp/src/Tree/Pattern/ParseTreePatternMatcher.cs","lineNumber":222,"sourceCode":"        /// or empty.\n        /// </exception>\n        /// <exception>\n        /// IllegalArgumentException\n        /// if\n        /// <paramref name=\"stop\"/>\n        /// is\n        /// <see langword=\"null\"/>\n        /// or empty.\n        /// </exception>\n        public virtual void SetDelimiters(string start, string stop, string escapeLeft)\n        {\n            if (string.IsNullOrEmpty(start))\n            {\n                throw new ArgumentException(\"start cannot be null or empty\");\n            }\n            if (string.IsNullOrEmpty(stop))\n            {\n                throw new ArgumentException(\"stop cannot be null or empty\");\n            }\n            this.start = start;\n            this.stop = stop;\n            this.escape = escapeLeft;\n        }\n\n        /// <summary>\n        /// Does\n        /// <paramref name=\"pattern\"/>\n        /// matched as rule\n        /// <paramref name=\"patternRuleIndex\"/>\n        /// match\n        /// <paramref name=\"tree\"/>\n        /// ?\n        /// </summary>\n        public virtual bool Matches(IParseTree tree, string pattern, int patternRuleIndex)\n        {\n            ParseTreePattern p = Compile(pattern, patternRuleIndex);","sourceCodeStart":204,"sourceCodeEnd":240,"githubUrl":"https://github.com/antlr/antlr4/blob/7d5770395bb7b02eb56e7c62662cb1d7c08f42a3/runtime/CSharp/src/Tree/Pattern/ParseTreePatternMatcher.cs#L204-L240","documentation":"ParseTreePatternMatcher.SetDelimiters rejects a null or empty stop delimiter. The stop delimiter closes a tag in a pattern string; without it the tag scanner cannot find tag boundaries, so the call fails fast. Note the escape (third) argument is not validated — only start and stop are.","triggerScenarios":"Calling matcher.SetDelimiters(\"[\", \"\", \"\\\\\") or SetDelimiters(\"[\", null, ...) — e.g. reading delimiters from user input where only the opening one was provided.","commonSituations":"Delimiter pairs configured from a single config value where the closing one is derived incorrectly; interactive tooling that lets users set tag delimiters; typos in the argument order (start/stop swapped or escape passed in the stop slot).","solutions":["Pass a non-empty stop delimiter, e.g. SetDelimiters(\"[\", \"]\", \"\\\\\").","Check both delimiter values with string.IsNullOrEmpty before calling and report which one is missing.","Keep the default delimiters ('<', '>') unless there is a concrete grammar conflict with angle brackets."],"exampleFix":"// before\nmatcher.SetDelimiters(\"[\", \"\", \"\\\\\");\n\n// after\nmatcher.SetDelimiters(\"[\", \"]\", \"\\\\\");","handlingStrategy":"validation","validationCode":"if (string.IsNullOrEmpty(start) || string.IsNullOrEmpty(stop)) throw new ConfigurationErrorsException(\"tag delimiters must be non-empty\");\nmatcher.SetDelimiters(start, stop, escape);","typeGuard":"static bool IsValidDelimiter(string s) => !string.IsNullOrEmpty(s);","tryCatchPattern":null,"preventionTips":["Treat delimiters as a pair and validate both together.","Unit-test delimiter configuration at startup before parsing begins."],"tags":["antlr","csharp","pattern-matcher","delimiters","validation"],"backgroundTag":null,"analyzedSha":"7d5770395bb7b02eb56e7c62662cb1d7c08f42a3","analyzedAt":"2026-08-14T14:47:56.354Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}