{"record":{"id":"fc1850cd2ff66c9e","repo":"can1357/oh-my-pi","slug":"operation-for-must-be-ready-or-exit","errorCode":null,"errorMessage":"operation.for must be ready or exit","messagePattern":"operation\\.for must be ready or exit","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"packages/coding-agent/src/launch/protocol.ts","lineNumber":372,"sourceCode":"\t\t\t};\n\t\tcase \"logs\":\n\t\t\treturn {\n\t\t\t\top,\n\t\t\t\tname: stringValue(source.name, \"operation.name\"),\n\t\t\t\tlines: numberValue(source.lines, \"operation.lines\"),\n\t\t\t\thead: booleanValue(source.head, \"operation.head\"),\n\t\t\t\tgrep: optionalString(source.grep, \"operation.grep\"),\n\t\t\t\tfollow: booleanValue(source.follow, \"operation.follow\"),\n\t\t\t\tcursor: optionalNumber(source.cursor, \"operation.cursor\"),\n\t\t\t\trenderTerminalRows:\n\t\t\t\t\tsource.renderTerminalRows === undefined\n\t\t\t\t\t\t? undefined\n\t\t\t\t\t\t: booleanValue(source.renderTerminalRows, \"operation.renderTerminalRows\"),\n\t\t\t\ttimeoutMs: numberValue(source.timeoutMs, \"operation.timeoutMs\"),\n\t\t\t};\n\t\tcase \"wait\": {\n\t\t\tconst target = stringValue(source.for, \"operation.for\");\n\t\t\tif (target !== \"ready\" && target !== \"exit\") throw new Error(\"operation.for must be ready or exit\");\n\t\t\treturn {\n\t\t\t\top,\n\t\t\t\tname: stringValue(source.name, \"operation.name\"),\n\t\t\t\tfor: target,\n\t\t\t\tpattern: optionalString(source.pattern, \"operation.pattern\"),\n\t\t\t\ttimeoutMs: numberValue(source.timeoutMs, \"operation.timeoutMs\"),\n\t\t\t};\n\t\t}\n\t\tcase \"send\":\n\t\t\treturn {\n\t\t\t\top,\n\t\t\t\tname: stringValue(source.name, \"operation.name\"),\n\t\t\t\tdata: optionalString(source.data, \"operation.data\"),\n\t\t\t\tsignal: source.signal === undefined ? undefined : daemonSignal(source.signal),\n\t\t\t};\n\t\tcase \"stop\":\n\t\t\treturn {\n\t\t\t\top,","sourceCodeStart":354,"sourceCodeEnd":390,"githubUrl":"https://github.com/can1357/oh-my-pi/blob/969062200754ea02cfac922e5ebb8c608c079e15/packages/coding-agent/src/launch/protocol.ts#L354-L390","documentation":"parseDaemonOperation validates the `wait` operation's `for` field, which must be the literal string \"ready\" or \"exit\". Any other value is rejected because the broker can only wait on those two daemon lifecycle states.","triggerScenarios":"Sending a daemon wire request with op \"wait\" and `for` set to anything other than \"ready\"/\"exit\" — e.g. \"started\", \"stopped\", missing field, or a typo.","commonSituations":"Hand-written RPC payloads against the daemon socket, scripts copied from an older protocol version where other wait targets existed, or a client/daemon version skew.","solutions":["Set `for` to exactly \"ready\" or \"exit\" in the request.","Check protocol.ts for the current set of supported wait targets.","Align client and daemon versions so both agree on operation fields.","If a new wait target is needed, extend parseDaemonOperation in protocol.ts and regenerate/rebuild."],"exampleFix":"// before\n{ \"op\": \"wait\", \"for\": \"started\", \"name\": \"main\", \"timeoutMs\": 5000 }\n// after\n{ \"op\": \"wait\", \"for\": \"ready\", \"name\": \"main\", \"timeoutMs\": 5000 }","handlingStrategy":"validation","validationCode":"const VALID_WAIT_TARGETS = [\"ready\", \"exit\"] as const;\nfunction buildWaitOp(forTarget: string) {\n  if (!VALID_WAIT_TARGETS.includes(forTarget as any)) throw new Error(`invalid wait target: ${forTarget}`);\n  return { op: \"wait\", for: forTarget };\n}","typeGuard":"const isValidWaitTarget = (v: unknown): v is \"ready\" | \"exit\" => v === \"ready\" || v === \"exit\";","tryCatchPattern":"try {\n  await broker.request({ op: \"wait\", for: target, name, timeoutMs });\n} catch (err) {\n  if (err.message.includes(\"operation.for must be\")) throw new Error(`bad wait target \"${target}\"; use ready|exit`);\n  throw err;\n}","preventionTips":["Centralize request building so op fields come from one typed factory","Use literal union types (\"ready\" | \"exit\") in client code","Keep protocol docs in sync with protocol.ts"],"tags":["protocol","validation","daemon","ipc"],"backgroundTag":"schema-validation-failed","analyzedSha":"969062200754ea02cfac922e5ebb8c608c079e15","analyzedAt":"2026-08-31T10:29:35.737Z","schemaVersion":2},"datasetVersion":"2026-08-31T14:17:45.589Z"}