can1357/oh-my-pi · error

Invalid log regex: ${error instanceof Error ? error.message

Error message

Invalid log regex: ${error instanceof Error ? error.message : String(error)}

What it means

The broker's readFiles log reader accepts an optional `grep` parameter compiled into a RegExp with the 'u' (unicode) flag. If `new RegExp(grep, 'u')` throws — invalid pattern syntax, or constructs illegal under the unicode flag such as unescaped lone surrogate pairs or invalid \\u escapes — the raw RegExp engine error is rethrown wrapped as 'Invalid log regex: <detail>' so callers know the filter string, not the log data, is at fault.

Source

Thrown at packages/coding-agent/src/launch/broker.ts:265

		logPath: string,
		previousPath: string,
		head: boolean,
		lines: number,
		cursor: number,
		grep?: string,
	): Promise<DaemonLogRead> {
		const [previous, current] = await Promise.all([fileTextSlice(previousPath, head), fileTextSlice(logPath, head)]);
		const combined = `${previous}${previous && current && !previous.endsWith("\n") ? "\n" : ""}${current}`;
		const terminalOutput = head
			? truncateHeadBytes(combined, LOG_READ_BYTES).text
			: truncateTailBytes(combined, LOG_READ_BYTES).text;
		let text = sanitizeText(terminalOutput);
		if (grep) {
			let pattern: RegExp;
			try {
				pattern = new RegExp(grep, "u");
			} catch (error) {
				throw new Error(`Invalid log regex: ${error instanceof Error ? error.message : String(error)}`);
			}
			text = text
				.split("\n")
				.filter(line => pattern.test(line))
				.join("\n");
		}
		const options = { maxLines: lines, maxBytes: 256 * 1024 };
		return {
			text: head ? truncateHead(text, options).content : truncateTail(text, options).content,
			terminalOutput,
			cursor,
		};
	}

	async #rotate(): Promise<void> {
		await this.#writer.end();
		await fs.rm(this.#previousPath, { force: true });
		await fs.rename(this.#path, this.#previousPath);

View on GitHub (pinned to 9690622007)

Solutions

  1. Fix the pattern syntax reported after 'Invalid log regex:' — check the exact character/position in the RegExp message
  2. Escape metacharacters (., *, [, ], (, ), etc.) that should be literal, e.g. \\[' instead of '['
  3. Test the pattern in isolation: new RegExp(pattern, 'u') in a REPL before passing it to readFiles
  4. Drop or simplify unicode-specific constructs if the /u flag is the problem (escape lone surrogates as \\u{...} code points)

Example fix

// before
await broker.readFiles({ grep: '[' }); // Invalid log regex: Unterminated character class
// after
await broker.readFiles({ grep: '\\[' }); // matches literal '['
// or validate first:
try { new RegExp(userGrep, 'u'); } catch { userGrep = userGrep.replace(/[.*+?^${}()|[\]\\]/g, '\\$&'); }
Defensive patterns

Strategy: validation

Validate before calling

function compileLogGrep(grep: string): RegExp {
  try { return new RegExp(grep, 'u'); } catch (e) {
    throw new Error(`Invalid log regex: ${e instanceof Error ? e.message : String(e)}`);
  }
}
// call compileLogGrep(userGrep) before invoking readFiles

Try / catch

try {
  await broker.readFiles({ grep: userPattern });
} catch (err) {
  if (err instanceof Error && err.message.startsWith('Invalid log regex:')) {
    // surface the engine detail to the user and fall back to unfiltered logs
    return broker.readFiles({});
  }
  throw err;
}

Prevention

When it happens

Trigger: Calling readFiles with grep set to a syntactically invalid pattern, e.g. '[' or 'a{2,1}', or a pattern only invalid with /u like '\\u{}' or a lone surrogate ('\\uD800' unpaired) that the unicode flag rejects.

Common situations: Users typing ad-hoc filter expressions in a UI that are forwarded verbatim to the broker; copying regexes from tools using different flavor syntax (e.g. lookbehind variants, possessive quantifiers) unsupported by the JS engine; forgetting to escape special characters like ( or *; enabling /u semantics inadvertently via this fixed flag.

Related errors


AI-assisted analysis of can1357/oh-my-pi@9690622007 (2026-08-31). Data as JSON: /api/errors/6aae14aa0c6c1000. Report an issue: GitHub.