can1357/oh-my-pi · error · Error
Unexpected broker response ${first.op}
Error message
Unexpected broker response ${first.op} What it means
`omp ps logs` issues an initial `{op:"logs"}` request and requires a logs-shaped reply to read `first.text` / `first.terminalRows` / `first.state`. This guard throws when the broker answers with any other op, so the log payload is absent and printing would read undefined fields.
Source
Thrown at packages/coding-agent/src/cli/ps-cli.ts:229
if (cmd.flags.json) console.log(JSON.stringify(daemon, null, 2));
else console.log(`${verb} ${daemonLabel(daemon)}`);
}
async function runLogs(cmd: PsCommandArgs, client: DaemonBrokerClient, name: string): Promise<void> {
const lines = Math.max(1, Math.min(1_000, Math.floor(cmd.flags.lines ?? 100)));
// Follow mode reads the full 1000-line window on every request so overlap
// trimming sees a stable, sliding tail; the initial print is cut to `lines`.
const first = await client.request({
op: "logs",
name,
lines: cmd.flags.follow ? 1_000 : lines,
head: cmd.flags.head,
grep: cmd.flags.grep,
follow: false,
renderTerminalRows: !cmd.flags.follow,
timeoutMs: 30_000,
});
if (first.op !== "logs") throw new Error(`Unexpected broker response ${first.op}`);
if (!cmd.flags.follow) {
const text = first.terminalRows !== undefined ? first.terminalRows.join("\n") : first.text.replace(/\n$/, "");
if (text) console.log(text);
console.log(chalk.dim(`[${name}: ${first.state}]`));
return;
}
const initial = first.text.replace(/\n$/, "").split("\n").slice(-lines).join("\n");
if (initial) process.stdout.write(`${initial}\n`);
let previous = first.text;
let cursor = first.cursor;
let state = first.state;
while (!TERMINAL_STATES[state]) {
const next = await client.request({
op: "logs",
name,
lines: 1_000,
head: false,
grep: cmd.flags.grep,View on GitHub (pinned to 9690622007)
Solutions
- Point the command at the right scope: pass `--dir <project>` or `--global <service>` matching where the daemon runs, and use the exact name from `omp ps --all`.
- Restart/reconnect the broker so CLI and broker protocol versions match.
- If the daemon has exited, check whether its metadata still exists (`<runtimeDir>/daemons/<name>/meta.json`) or view persisted logs directly from that directory.
Example fix
// before
const first = await client.request({ op: "logs", ... });
if (first.op !== "logs") throw new Error(`Unexpected broker response ${first.op}`);
// after
const first = await client.request({ op: "logs", ... });
if (first.op === "error") throw new Error(`Cannot read logs: ${first.message}`);
if (first.op !== "logs") throw new Error(`Unexpected broker response ${first.op}`); Defensive patterns
Strategy: type-guard
Validate before calling
const listing = await client.request({ op: "list" });
if (listing.op === "list" && !listing.daemons.some(d => d.name === name)) {
throw new Error(`No daemon "${name}" in this scope; check --dir/--global`);
} Type guard
function isLogsResponse(r: { op: string }): r is { op: "logs"; text: string; terminalRows?: string[]; state: string; cursor?: string } {
return r.op === "logs";
} Try / catch
try {
const first = await client.request({ op: "logs", name, follow: false, timeoutMs: 30_000 });
if (!isLogsResponse(first)) throw new Error(`Unexpected broker response ${first.op}`);
} catch (err) {
console.error(chalk.red(err instanceof Error ? err.message : String(err)));
process.exitCode = 1;
} Prevention
- Target the correct scope with --dir/--global and the exact daemon name from `omp ps --all`.
- Handle error-op replies explicitly to distinguish 'daemon gone' from protocol mismatch.
- Restart brokers after upgrading omp.
When it happens
Trigger: `runLogs` where the first `client.request({op:"logs", ..., follow:false})` resolves with a response whose `op` is not "logs" — e.g. an error/not-found response, or a broker running an incompatible protocol version.
Common situations: Fetching logs for a daemon that the connected broker doesn't own (wrong `--dir`/`--global` scope so the name resolves differently); stale broker after an omp upgrade; the daemon exited and was pruned so the broker replies with an error op.
Related errors
- Unexpected broker response ${next.op}
- Unexpected broker response ${result.op}
- Unexpected broker response ${result.op}
- Unexpected response ${result.op}
- blob daemon ${input} responded ${response.status}
AI-assisted analysis of can1357/oh-my-pi@9690622007 (2026-08-31).
Data as JSON: /api/errors/d1657f896855ccbc.
Report an issue: GitHub.