ruvnet/ruflo · warning
Pattern rejected: exceeds maximum length of 500 characters
Error message
Pattern rejected: exceeds maximum length of 500 characters
What it means
addPattern() enforces a hard 500-character sanity bound on classification patterns, checked after the ReDoS heuristic. Even a safe regex of unbounded length is a compile-cost and review burden, so longer patterns are rejected outright with a fixed message. The limit is on the pattern string itself, not on matched input.
Source
Thrown at v3/@claude-flow/guidance/src/authority.ts:676
}
/**
* Add a pattern to a classification.
*
* Validates the pattern against ReDoS heuristics before accepting it.
* Rejects patterns with nested quantifiers (e.g., `(a+)+`) that can
* cause catastrophic backtracking.
*
* @throws Error if the pattern is invalid regex or contains ReDoS-prone constructs
*/
addPattern(classification: IrreversibilityClass, pattern: string): void {
// ReDoS heuristic: reject nested quantifiers like (a+)+, (a*)+, (a+)*, etc.
if (/([+*]|\{[0-9]+,?\})\s*\)[\s]*[+*]|\{[0-9]+,?\}/.test(pattern)) {
throw new Error(`Pattern rejected: nested quantifiers detected (potential ReDoS): ${pattern}`);
}
// Also reject patterns longer than 500 chars as a sanity bound
if (pattern.length > 500) {
throw new Error(`Pattern rejected: exceeds maximum length of 500 characters`);
}
const regex = new RegExp(pattern, 'i');
switch (classification) {
case 'irreversible':
this.irreversiblePatterns.push(regex);
break;
case 'costly-reversible':
this.costlyReversiblePatterns.push(regex);
break;
case 'reversible':
this.reversiblePatterns.push(regex);
break;
}
}
// ===== Private =====View on GitHub (pinned to fa13ee4ad6)
Solutions
- Split one long pattern into several addPattern() calls under the same classification
- Replace long literal alternations with a prefix or a shorter wildcard pattern
- Assert `pattern.length <= 500` in the code that generates patterns
- Store keyword lists as data and match with a Set instead of one mega-regex
Example fix
// before
authority.addPattern('irreversible', veryLongAlternation); // >500 chars, throws
// after
for (const chunk of chunkByLength(allLiterals, 400)) {
authority.addPattern('irreversible', chunk);
} Defensive patterns
Strategy: validation
Validate before calling
if (pattern.length > 500) {
throw new Error('pattern exceeds the 500-char ledger limit');
}
authority.addPattern(classification, pattern); Prevention
- Split large keyword lists into multiple patterns
- Generate patterns from bounded keyword sets, not unbounded inventories
- Add a length assertion to pattern-generation code and tests
When it happens
Trigger: Generating a giant alternation of literals, e.g. `(path\\to\\a|path\\to\\b|... hundreds more)` that crosses 500 chars; concatenating many keywords into one pattern in a loop; LLM-generated patterns that enumerate exhaustive variants.
Common situations: Auto-building irreversible/costly-reversible pattern lists from filesystem inventories or log catalogs; keyword blacklists grown over time until they silently cross the cap.
Related errors
- Pattern rejected: nested quantifiers detected (potential ReD
- namespace contains invalid characters (allowed: alphanumeric
- localCompute: no adapter for graphId=${input.graphId}
- Invalid completion type
- Router multimodal is enabled but LLM_ROUTER_MULTIMODAL_MODEL
AI-assisted analysis of ruvnet/ruflo@fa13ee4ad6 (2026-08-18).
Data as JSON: /api/errors/434c5e82850f61ed.
Report an issue: GitHub.