iOfficeAI/OfficeCLI · error · ArgumentException

Regex pattern '{pattern}' exceeded {RegexMatchTimeout.TotalS

Error message

Regex pattern '{pattern}' exceeded {RegexMatchTimeout.TotalSeconds}s match timeout (catastrophic backtracking?)

What it means

Thrown by FindHelpers when a regex match exceeds the 5-second timeout (FindHelpers.RegexMatchTimeout). The bound exists specifically to stop catastrophic-backtracking patterns (e.g. '(a+)+b') from hanging the process; the timeout is rewrapped as an ArgumentException naming the pattern.

Source

Thrown at src/officecli/Core/FindHelpers.cs:64

        if (isRegex)
        {
            try
            {
                // Bound matching with a hard timeout so catastrophic-backtracking
                // patterns (e.g. "(a+)+b") fail fast instead of hanging the process.
                foreach (Match m in Regex.Matches(fullText, pattern, RegexOptions.None, RegexMatchTimeout))
                {
                    if (m.Length > 0) // skip zero-length matches
                        ranges.Add((m.Index, m.Length));
                }
            }
            catch (RegexParseException ex)
            {
                throw new ArgumentException($"Invalid regex pattern '{pattern}': {ex.Message}", ex);
            }
            catch (RegexMatchTimeoutException ex)
            {
                throw new ArgumentException(
                    $"Regex pattern '{pattern}' exceeded {RegexMatchTimeout.TotalSeconds}s match timeout (catastrophic backtracking?)",
                    ex);
            }
        }
        else
        {
            int idx = 0;
            while ((idx = fullText.IndexOf(pattern, idx, StringComparison.Ordinal)) >= 0)
            {
                ranges.Add((idx, pattern.Length));
                idx += pattern.Length;
            }
        }
        return ranges;
    }
}

View on GitHub (pinned to 1ced45e900)

Solutions

  1. Rewrite the pattern to avoid catastrophic backtracking (eliminate nested quantifiers, use atomic/possessive constructs or anchoring).
  2. Narrow the search scope (search a specific sheet/region) to reduce input size.
  3. Pre-validate user-supplied regex against representative input with a local timeout before using it.

Example fix

// before
Find(sheet, pattern: "(a+)+b", useRegex: true); // catastrophic
// after
Find(sheet, pattern: "a+b", useRegex: true); // linear
Defensive patterns

Strategy: try-catch

Validate before calling

static bool MatchesWithinTimeout(string text, string pattern, TimeSpan timeout)
{ try { return Regex.IsMatch(text, pattern, RegexOptions.None, timeout); } catch (RegexMatchTimeoutException) { return false; } }

Try / catch

try { Find(sheet, pattern, useRegex: true); }
catch (ArgumentException ex) when (ex.Message.Contains("match timeout"))
{ /* simplify the pattern or narrow scope */ }

Prevention

When it happens

Trigger: Calling a find/search API with a regex that takes longer than 5 seconds to match against the target text. Patterns with nested quantifiers or overlapping alternatives on long inputs are the usual cause.

Common situations: An evil/inefficient pattern on large document text; user-supplied regex not vetted for performance; a pattern that performs well on short input but blows up on production-size text.

Understand the failure class

Related errors


AI-assisted analysis of iOfficeAI/OfficeCLI@1ced45e900 (2026-08-13). Data as JSON: /api/errors/0cfcd85bbe5595b6. Report an issue: GitHub.