{"record":{"id":"5c387e4f24ada3eb","repo":"can1357/oh-my-pi","slug":"invalid-regex-err-message","errorCode":null,"errorMessage":"Invalid regex: ${err.message}","messagePattern":"Invalid regex: (.+?)","errorType":"exception","errorClass":"ToolError","httpStatus":null,"severity":"error","filePath":"packages/coding-agent/src/tools/grep.ts","lineNumber":1241,"sourceCode":"\t\t\t\t\t\t\t\t\thidden: true,\n\t\t\t\t\t\t\t\t\tgitignore: useGitignore,\n\t\t\t\t\t\t\t\t\tmaxCount: nativeMaxCount,\n\t\t\t\t\t\t\t\t\tcontextBefore: normalizedContextBefore,\n\t\t\t\t\t\t\t\t\tcontextAfter: normalizedContextAfter,\n\t\t\t\t\t\t\t\t\tmaxColumns: DEFAULT_MAX_COLUMN,\n\t\t\t\t\t\t\t\t\tmode: effectiveOutputMode,\n\t\t\t\t\t\t\t\t\tmaxCountPerFile: nativeMaxCountPerFile,\n\t\t\t\t\t\t\t\t\tsignal,\n\t\t\t\t\t\t\t\t\ttimeoutMs: SEARCH_GREP_TIMEOUT_MS,\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\tundefined,\n\t\t\t\t\t\t\t);\n\t\t\t\t\t\t\tskippedOversizedCount = result.skippedOversized ?? 0;\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t} catch (err) {\n\t\t\t\t\tif (err instanceof Error && /^regex(?: parse)? error/i.test(err.message)) {\n\t\t\t\t\t\tthrow new ToolError(err.message.replace(/^regex(?: parse)? error:?\\s*/i, \"Invalid regex: \"));\n\t\t\t\t\t}\n\t\t\t\t\tif (err instanceof Error && err.message.includes(\"Aborted: Timeout\")) {\n\t\t\t\t\t\tthrow new ToolError(\n\t\t\t\t\t\t\t`Grep timed out after ${SEARCH_GREP_TIMEOUT_MS / 1000}s; narrow paths or pattern, or scope with \\`glob\\` first`,\n\t\t\t\t\t\t);\n\t\t\t\t\t}\n\t\t\t\t\tthrow err;\n\t\t\t\t}\n\t\t\t\tlet virtualResult: GrepResult;\n\t\t\t\ttry {\n\t\t\t\t\tvirtualResult = await searchVirtualResources(\n\t\t\t\t\t\tvirtualResources,\n\t\t\t\t\t\tnormalizedPattern,\n\t\t\t\t\t\tignoreCase,\n\t\t\t\t\t\teffectiveMultiline,\n\t\t\t\t\t\tnormalizedContextBefore,\n\t\t\t\t\t\tnormalizedContextAfter,\n\t\t\t\t\t\tINTERNAL_TOTAL_CAP,","sourceCodeStart":1223,"sourceCodeEnd":1259,"githubUrl":"https://github.com/can1357/oh-my-pi/blob/969062200754ea02cfac922e5ebb8c608c079e15/packages/coding-agent/src/tools/grep.ts#L1223-L1259","documentation":"The grep engine rejected the pattern because it is not valid regular expression syntax (e.g. unbalanced parenthesis, dangling quantifier, invalid escape). The tool catches the underlying regex parse error and rewrites it as \"Invalid regex: ...\" so the cause is clear.","triggerScenarios":"grep with patterns like \"foo(\", \"a{2,1}\", \"\\\\\", or \"[a-\"; patterns built by string interpolation that accidentally include regex metacharacters.","commonSituations":"Searching for literal text containing (, ), [, +, or ? without escaping; user input passed directly as a regex; Rust-regex vs JS regex syntax differences in lookbehind/backreferences.","solutions":["Fix the regex syntax (balance parens/brackets, escape metacharacters with \\\\)","For literal text search, escape metacharacters: const esc = s.replace(/[.*+?^${}()|[\\]\\\\]/g, \"\\\\$&\")","Check for unsupported constructs (backreferences/lookaround may be unsupported by the engine)"],"exampleFix":"// before\nawait grep({ pattern: `call_${userInput}(` });\n// after\nconst esc = userInput.replace(/[.*+?^${}()|[\\]\\\\]/g, \"\\\\$&\");\nawait grep({ pattern: `call_${esc}\\\\(` });","handlingStrategy":"validation","validationCode":"try { new RegExp(pattern); } catch (e) { throw new Error(`Invalid grep regex: ${e.message}`); }","typeGuard":"const isValidRegex = (p: string): boolean => { try { new RegExp(p); return true; } catch { return false; } };","tryCatchPattern":"try {\n  await grep({ pattern });\n} catch (err) {\n  if (err instanceof ToolError && err.message.startsWith(\"Invalid regex:\")) {\n    // escape metacharacters and retry as literal\n  } else throw err;\n}","preventionTips":["Escape user text with a metacharacter escaper before building regex patterns","Test patterns in a regex validator, noting engine-specific syntax limits"],"tags":["grep","regex","validation"],"backgroundTag":"invalid-regex","analyzedSha":"969062200754ea02cfac922e5ebb8c608c079e15","analyzedAt":"2026-08-31T10:29:35.737Z","schemaVersion":2},"datasetVersion":"2026-08-31T14:17:45.589Z"}