can1357/oh-my-pi · warning · Error

Unexpected broker response ${result.op}

Error message

Unexpected broker response ${result.op}

What it means

`collectScope` queries a live broker (identified by `brokerPid`) with `{op:"list"}` and requires a list-shaped reply to enumerate daemons. The whole call sits inside a try/catch that falls back to the offline (persisted metadata) view, so this throw signals the broker answered but with the wrong response type, degrading the report to snapshots from disk rather than crashing the CLI.

Source

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

/**
 * Collect daemons for one scope. Live brokers are authoritative; dead scopes
 * fall back to persisted snapshots, downgrading non-detached "running" records
 * to exited (their broker took them down with it) and flagging detached
 * survivors as unsupervised.
 */
export async function collectScope(scope: PsScope): Promise<PsScopeReport> {
	const persisted = await readPersistedDaemons(scope.runtimeDir);
	if (scope.brokerPid !== undefined) {
		try {
			const client = await scopeClient(scope);
			if (client) {
				try {
					if (scope.projectDir === undefined) {
						const ping = await client.request({ op: "ping" });
						if (ping.op === "ping") scope.projectDir = ping.projectDir;
					}
					const result = await client.request({ op: "list" });
					if (result.op !== "list") throw new Error(`Unexpected broker response ${result.op}`);
					return {
						scope,
						daemons: result.daemons.map(snapshot => ({
							snapshot,
							command: formatCommand(persisted.get(snapshot.name)?.spec),
							cwd: persisted.get(snapshot.name)?.spec.cwd,
							supervised: true,
						})),
					};
				} finally {
					client.close();
				}
			}
		} catch {
			// Broker died or refused mid-query; fall through to the offline view.
		}
	}
	const daemons: PsDaemonRow[] = [];

View on GitHub (pinned to 9690622007)

Solutions

  1. Treat the offline rows as a symptom: find the real broker, kill it, and let the CLI revive a fresh one from the current omp version.
  2. Upgrade or reinstall omp so CLI and broker protocol versions match.
  3. If you see this repeatedly in code, check whether `collectScope`'s fallback path is being hit by inspecting the `supervised: false` rows in `omp ps` output.

Example fix

// before
const result = await client.request({ op: "list" });
if (result.op !== "list") throw new Error(`Unexpected broker response ${result.op}`);
// after
const result = await client.request({ op: "list" });
if (result.op === "error") logger.warn("broker list refused", { scope, message: result.message });
if (result.op !== "list") throw new Error(`Unexpected broker response ${result.op}`);
Defensive patterns

Strategy: fallback

Validate before calling

const brokerInfo = await Bun.file(path.join(scope.runtimeDir, "broker.json")).json().catch(() => null);
if (!brokerInfo || brokerInfo.protocolVersion !== EXPECTED_PROTOCOL) {
  logger.warn("broker protocol mismatch; using persisted snapshots", { runtimeDir: scope.runtimeDir });
}

Type guard

function isListResponse(r: { op: string }): r is { op: "list"; daemons: DaemonSnapshot[] } {
  return r.op === "list";
}

Try / catch

try {
  const result = await client.request({ op: "list" });
  if (!isListResponse(result)) throw new Error(`Unexpected broker response ${result.op}`);
  return { scope, daemons: result.daemons.map(toRow), supervised: true };
} catch {
  return offlineReport(scope, persisted); // existing fallback path
}

Prevention

When it happens

Trigger: A scope whose `brokerPid` is set accepts the `{op:"list"}` request but responds with an op other than "list" — e.g. an error response, a ping-shaped reply, or a broker built from different protocol code. The throw is swallowed by the surrounding catch and the scope renders from persisted snapshots.

Common situations: A stale pid-file points at a socket now owned by a different/older broker; version-skewed broker after an omp upgrade; a proxy on the runtime socket returning error envelopes.

Related errors


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