{"record":{"id":"434c5e82850f61ed","repo":"ruvnet/ruflo","slug":"pattern-rejected-exceeds-maximum-length-of-500-ch","errorCode":null,"errorMessage":"Pattern rejected: exceeds maximum length of 500 characters","messagePattern":"Pattern rejected: exceeds maximum length of 500 characters","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"warning","filePath":"v3/@claude-flow/guidance/src/authority.ts","lineNumber":676,"sourceCode":"  }\n\n  /**\n   * Add a pattern to a classification.\n   *\n   * Validates the pattern against ReDoS heuristics before accepting it.\n   * Rejects patterns with nested quantifiers (e.g., `(a+)+`) that can\n   * cause catastrophic backtracking.\n   *\n   * @throws Error if the pattern is invalid regex or contains ReDoS-prone constructs\n   */\n  addPattern(classification: IrreversibilityClass, pattern: string): void {\n    // ReDoS heuristic: reject nested quantifiers like (a+)+, (a*)+, (a+)*, etc.\n    if (/([+*]|\\{[0-9]+,?\\})\\s*\\)[\\s]*[+*]|\\{[0-9]+,?\\}/.test(pattern)) {\n      throw new Error(`Pattern rejected: nested quantifiers detected (potential ReDoS): ${pattern}`);\n    }\n    // Also reject patterns longer than 500 chars as a sanity bound\n    if (pattern.length > 500) {\n      throw new Error(`Pattern rejected: exceeds maximum length of 500 characters`);\n    }\n\n    const regex = new RegExp(pattern, 'i');\n\n    switch (classification) {\n      case 'irreversible':\n        this.irreversiblePatterns.push(regex);\n        break;\n      case 'costly-reversible':\n        this.costlyReversiblePatterns.push(regex);\n        break;\n      case 'reversible':\n        this.reversiblePatterns.push(regex);\n        break;\n    }\n  }\n\n  // ===== Private =====","sourceCodeStart":658,"sourceCodeEnd":694,"githubUrl":"https://github.com/ruvnet/ruflo/blob/fa13ee4ad60ac2090b1480656eb233521790d640/v3/@claude-flow/guidance/src/authority.ts#L658-L694","documentation":"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.","triggerScenarios":"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.","commonSituations":"Auto-building irreversible/costly-reversible pattern lists from filesystem inventories or log catalogs; keyword blacklists grown over time until they silently cross the cap.","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"],"exampleFix":"// before\nauthority.addPattern('irreversible', veryLongAlternation); // >500 chars, throws\n\n// after\nfor (const chunk of chunkByLength(allLiterals, 400)) {\n  authority.addPattern('irreversible', chunk);\n}","handlingStrategy":"validation","validationCode":"if (pattern.length > 500) {\n  throw new Error('pattern exceeds the 500-char ledger limit');\n}\nauthority.addPattern(classification, pattern);","typeGuard":null,"tryCatchPattern":null,"preventionTips":["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"],"tags":["regex","input-length-limit","validation","guidance","authority"],"backgroundTag":"input-length-limit-exceeded","analyzedSha":"fa13ee4ad60ac2090b1480656eb233521790d640","analyzedAt":"2026-08-18T21:34:22.708Z","schemaVersion":2},"datasetVersion":"2026-08-22T09:17:25.309Z"}