{"record":{"id":"46c1a1a97748dca0","repo":"iOfficeAI/OfficeCLI","slug":"invalid-regex-pattern-pattern-ex-message","errorCode":null,"errorMessage":"Invalid regex pattern '{pattern}': {ex.Message}","messagePattern":"Invalid regex pattern '(.+?)': (.+?)","errorType":"exception","errorClass":"ArgumentException","httpStatus":null,"severity":"error","filePath":"src/officecli/Core/FindHelpers.cs","lineNumber":60,"sourceCode":"    /// </summary>\n    internal static List<(int Start, int Length)> FindMatchRanges(string fullText, string pattern, bool isRegex)\n    {\n        var ranges = new List<(int Start, int Length)>();\n        if (isRegex)\n        {\n            try\n            {\n                // Bound matching with a hard timeout so catastrophic-backtracking\n                // patterns (e.g. \"(a+)+b\") fail fast instead of hanging the process.\n                foreach (Match m in Regex.Matches(fullText, pattern, RegexOptions.None, RegexMatchTimeout))\n                {\n                    if (m.Length > 0) // skip zero-length matches\n                        ranges.Add((m.Index, m.Length));\n                }\n            }\n            catch (RegexParseException ex)\n            {\n                throw new ArgumentException($\"Invalid regex pattern '{pattern}': {ex.Message}\", ex);\n            }\n            catch (RegexMatchTimeoutException ex)\n            {\n                throw new ArgumentException(\n                    $\"Regex pattern '{pattern}' exceeded {RegexMatchTimeout.TotalSeconds}s match timeout (catastrophic backtracking?)\",\n                    ex);\n            }\n        }\n        else\n        {\n            int idx = 0;\n            while ((idx = fullText.IndexOf(pattern, idx, StringComparison.Ordinal)) >= 0)\n            {\n                ranges.Add((idx, pattern.Length));\n                idx += pattern.Length;\n            }\n        }\n        return ranges;","sourceCodeStart":42,"sourceCodeEnd":78,"githubUrl":"https://github.com/iOfficeAI/OfficeCLI/blob/1ced45e900782c5083ed550ddf328ee974e425e7/src/officecli/Core/FindHelpers.cs#L42-L78","documentation":"Thrown by FindHelpers when a caller-supplied regex pattern fails to parse (RegexParseException). The match is run with a hard timeout to defend against catastrophic backtracking; a structurally invalid pattern is caught and rewrapped as an ArgumentException that names the pattern and the parser's message.","triggerScenarios":"Calling a find/search API with regex enabled (e.g. a find/findAll option that treats the query as a regular expression) using a syntactically invalid pattern such as unbalanced parentheses, a dangling quantifier, or an invalid character class.","commonSituations":"User-typed regex with a typo ('(' unclosed, '*' at start, '[invalid range); regex built from unescaped dynamic input that injects metacharacters; a pattern valid in another regex flavor but not .NET.","solutions":["Fix the pattern syntax (balance groups, escape metacharacters, valid ranges).","Test the pattern with Regex() in isolation before passing it.","If the pattern comes from user input, validate it with a try/new Regex(...) first and reject early."],"exampleFix":"// before\nFind(sheet, pattern: \"(foo\", useRegex: true); // unbalanced group\n// after\nFind(sheet, pattern: \"(foo)\", useRegex: true);","handlingStrategy":"try-catch","validationCode":"static void ValidateRegex(string pattern)\n{\n    _ = new Regex(pattern, RegexOptions.None, FindHelpers.RegexMatchTimeout);\n}","typeGuard":"static bool IsValidRegex(string pattern)\n{ try { _ = new Regex(pattern); return true; } catch { return false; } }","tryCatchPattern":"try { Find(sheet, pattern, useRegex: true); }\ncatch (ArgumentException ex) when (ex.Message.Contains(\"Invalid regex pattern\"))\n{ /* report bad pattern to user */ }","preventionTips":["Pre-compile user-supplied regex to catch syntax errors early.","Escape dynamic text before embedding it in a pattern."],"tags":["find","regex","validation"],"backgroundTag":null,"analyzedSha":"1ced45e900782c5083ed550ddf328ee974e425e7","analyzedAt":"2026-08-13T13:01:07.193Z","schemaVersion":2},"datasetVersion":"2026-08-13T14:17:21.547Z"}