can1357/oh-my-pi · error
Invalid wait regex: ${error instanceof Error ? error.message
Error message
Invalid wait regex: ${error instanceof Error ? error.message : String(error)} What it means
DaemonBroker's wait/send operation handler compiles operation.pattern with new RegExp(pattern, "u") to match daemon log output during a wait. An invalid pattern aborts the wait before any matching is attempted, wrapping the RegExp syntax error in this message. Like the readiness check, it enforces unicode-mode validity.
Source
Thrown at packages/coding-agent/src/launch/broker.ts:1071
timedOut,
state: record.snapshot.state,
};
}
async #wait(operation: Extract<DaemonOperation, { op: "wait" }>): Promise<DaemonRpcResult> {
const record = this.#record(operation.name);
// A wait observes exactly one launch generation. Automatic or explicit
// relaunches reuse the managed record, so polling the record without this
// binding can hang past an exit or consume the replacement's output.
const boundGeneration = record.generation;
await this.#refreshDetached(record);
let matched: string | undefined;
let pattern: RegExp | undefined;
if (operation.pattern) {
try {
pattern = new RegExp(operation.pattern, "u");
} catch (error) {
throw new Error(`Invalid wait regex: ${error instanceof Error ? error.message : String(error)}`);
}
}
// Readiness was actually observed: the sticky readyAt survives a fast
// ready→exit, a live "ready" state, or a "running" daemon with no ready spec.
const readyObserved = (): boolean =>
record.snapshot.readyAt !== undefined ||
record.snapshot.state === "ready" ||
(record.snapshot.state === "running" && !record.spec.ready);
const generationEnded = (): boolean =>
record.generation !== boundGeneration || record.snapshot.state === "restarting";
const condition = (): boolean => {
if (generationEnded()) return true;
if (pattern) {
const match = pattern.exec(record.readinessBuffer);
if (!match) return false;
matched = match[0].slice(0, 500);
return true;
}View on GitHub (pinned to 9690622007)
Solutions
- Validate the pattern client-side with `new RegExp(pattern, "u")` before issuing the wait operation.
- Escape user-provided fragments with a regex-escape helper before embedding them in the pattern.
- Omit pattern to wait purely on state/readiness instead of log matching.
Example fix
// before
await broker.wait({ name: "server", pattern: "ready (" + userPort + ")" });
// after
const safe = userPort.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
const pattern = `ready \\(${safe}\\)`;
new RegExp(pattern, "u"); // validate early
await broker.wait({ name: "server", pattern }); Defensive patterns
Strategy: validation
Validate before calling
if (op.pattern !== undefined) {
try { new RegExp(op.pattern, "u"); }
catch (e) { throw new Error(`Bad wait pattern: ${e.message}`); }
} Type guard
function isValidRegexU(p: unknown): p is string {
if (typeof p !== "string") return false;
try { new RegExp(p, "u"); return true; } catch { return false; }
} Try / catch
try {
await broker.wait({ name, pattern, timeoutMs });
} catch (err) {
if (err instanceof Error && err.message.startsWith("Invalid wait regex:")) {
// correct or drop the pattern, then retry
} else throw err;
} Prevention
- Regex-escape any dynamic/user-supplied fragments before composing the pattern.
- Compile the pattern once at construction time so invalid patterns fail fast, not at wait time.
- Prefer waiting on state/ready flags over log regexes when possible.
When it happens
Trigger: Calling a wait operation ({ op: "wait", pattern: "..." }) with a syntactically invalid regex or one illegal under the 'u' flag (dangling quantifiers, unbalanced groups, bad \u escapes).
Common situations: Patterns built dynamically by string concatenation that end up malformed; unescaped user input embedded into a pattern; JSON config backslash escaping mistakes.
Related errors
- err.to_string() (invalid regex pattern)
- Invalid log regex: ${error instanceof Error ? error.message
- Invalid readiness regex: ${error instanceof Error ? error.me
- Invalid regex: ${err.message}
- Unsupported language '{value}'. Supported: {}
AI-assisted analysis of can1357/oh-my-pi@9690622007 (2026-08-31).
Data as JSON: /api/errors/1d16028cfdb62156.
Report an issue: GitHub.