can1357/oh-my-pi · error · Error

Unexpected broker response ${next.op}

Error message

Unexpected broker response ${next.op}

What it means

In follow mode `runLogs` polls the broker with `{op:"logs", follow:true, cursor}` and expects each reply to be a logs response carrying new `text` and a `cursor`. This guard throws when a follow-poll reply has a different op — the loop would otherwise read `next.text`/`next.cursor` on a foreign response shape.

Source

Thrown at packages/coding-agent/src/cli/ps-cli.ts:253

	}
	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,
			follow: true,
			cursor,
			renderTerminalRows: false,
			timeoutMs: 30_000,
		});
		if (next.op !== "logs") throw new Error(`Unexpected broker response ${next.op}`);
		// The broker always returns the tail window (cursor is only a wait
		// watermark), so trim the part we already printed.
		const fresh = next.text.slice(overlapLength(previous, next.text));
		if (fresh) process.stdout.write(fresh.endsWith("\n") ? fresh : `${fresh}\n`);
		previous = next.text;
		cursor = next.cursor;
		state = next.state;
	}
	console.log(chalk.dim(`[${name}: ${state}]`));
}

/** Longest suffix of `previous` that is a prefix of `next` — the already-printed portion of a tail window. */
function overlapLength(previous: string, next: string): number {
	for (let k = Math.min(previous.length, next.length); k > 0; k--) {
		const offset = previous.length - k;
		let match = true;
		for (let i = 0; i < k; i++) {
			if (previous.charCodeAt(offset + i) !== next.charCodeAt(i)) {

View on GitHub (pinned to 9690622007)

Solutions

  1. Re-run `omp ps logs --follow` after confirming the daemon still exists in `omp ps --all`.
  2. Check the broker process is alive and from the same omp version as the CLI; restart the broker if it was upgraded mid-session.
  3. Wrap the follow loop's request in a catch that exits the poll loop cleanly on error ops instead of treating every reply as logs.

Example fix

// before
const next = await client.request({ op: "logs", name, follow: true, cursor, ... });
if (next.op !== "logs") throw new Error(`Unexpected broker response ${next.op}`);
// after
const next = await client.request({ op: "logs", name, follow: true, cursor, ... });
if (next.op === "error") break; // daemon gone; end follow cleanly
if (next.op !== "logs") throw new Error(`Unexpected broker response ${next.op}`);
Defensive patterns

Strategy: try-catch

Validate before calling

if (previous === undefined && !(await client.request({ op: "list" }).then(r => r.op === "list" && r.daemons.some(d => d.name === name)))) {
  throw new Error(`Daemon "${name}" not found; follow aborted`);
}

Type guard

function isLogsResponse(r: { op: string }): r is { op: "logs"; text: string; cursor: string; state: string } {
  return r.op === "logs";
}

Try / catch

try {
  while (following) {
    const next = await client.request({ op: "logs", name, follow: true, cursor });
    if (!isLogsResponse(next)) break; // end follow cleanly on foreign/error replies
    /* print fresh text */
    cursor = next.cursor;
  }
} catch (err) {
  console.error(chalk.red(`follow ended: ${err instanceof Error ? err.message : String(err)}`));
}

Prevention

When it happens

Trigger: A `--follow` logs session where an intermediate `client.request({op:"logs", follow:true, cursor, ...})` resolves with a non-"logs" op — typically the broker switching to an error response mid-stream (daemon removed, broker shutting down) or a protocol version change.

Common situations: Following logs while the daemon is stopped/removed underneath the stream; the broker dies or is upgraded mid-follow and the revived broker speaks a different protocol; long-running follow sessions crossing an omp upgrade.

Related errors


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