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
- 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.
- Upgrade or reinstall omp so CLI and broker protocol versions match.
- 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
- Keep the offline fallback path so a bad broker reply degrades to persisted metadata.
- Kill stale brokers after omp upgrades so pid files don't point at mismatched brokers.
- Log the offending op inside the catch to make the fallback diagnosable.
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
- Unexpected broker response ${result.op}
- Unexpected broker response ${first.op}
- Unexpected broker response ${next.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/79d2e317c64ee523.
Report an issue: GitHub.