jackwener/OpenCLI · error · CommandExecutionError
expected array of rows from server, got ${typeof list} (cont
Error message
expected array of rows from server, got ${typeof list} (contract drift?) What it means
message-read.js expects the server evaluate result (after dispatchEvaluateResult) to be an array of thread/message rows so it can map each via mapRow. If the normalized result is not an array, it throws this CommandExecutionError indicating a server/CLI contract drift.
Source
Thrown at clis/slock/message-read.js:83
const params = {
isUuid, channel, after, before, limit, noThreads, override,
parentTarget: tt?.parentTarget ?? '',
parentMsgId: tt?.parentMsgId ?? '',
isThread: !!tt,
};
const snippet = buildReadSnippet(params);
const result = await page.evaluate(`(async () => { ${snippet} })()`);
if (result?.kind === 'no-thread') {
return [{
id: '', seq: null, createdAt: '', senderName: '',
content: `(${result.parent} — no thread yet, 0 replies.)`,
threadChannelId: null, replyCount: 0, unreadCount: 0, lastReplyAt: null,
}];
}
const list = dispatchEvaluateResult(result);
if (!Array.isArray(list)) {
throw new CommandExecutionError(`expected array of rows from server, got ${typeof list} (contract drift?)`);
}
const threadsMap = result.meta?.threadsMap ?? {};
const threadsDegraded = result.meta?.threadsDegraded === true;
const mapArg = threadsDegraded ? null : threadsMap;
const rows = list.map((m) => mapRow(m, mapArg));
if (threadsDegraded) {
rows.unshift({
id: '', seq: null, createdAt: '', senderName: '',
content: '(threads-enrichment unavailable — replyCount/threadChannelId set to null. Retry to get reply counts.)',
threadChannelId: null, replyCount: null, unreadCount: null, lastReplyAt: null,
});
}
return rows;
},
});
function buildReadSnippet(p) {
const target = JSON.stringify(p.channel.replace(/^#/, '').toLowerCase());View on GitHub (pinned to 49907e53dc)
Solutions
- Update the CLI to the server's current response contract (check where the array is now nested).
- Log the raw `result`/`list` before the throw to inspect the actual shape.
- Confirm active server and auth are valid so the real payload is returned.
- Check release notes for breaking API changes to the messages endpoint.
Example fix
// before const list = dispatchEvaluateResult(result); // after const raw = dispatchEvaluateResult(result); const list = Array.isArray(raw) ? raw : (raw.messages || raw.rows || []);
Defensive patterns
Strategy: type-guard
Validate before calling
const list = dispatchEvaluateResult(result);
if (!Array.isArray(list)) throw new Error(`unexpected message-read payload: ${JSON.stringify(list).slice(0,200)}`); Type guard
function isRowArray(v) { return Array.isArray(v); } Try / catch
try { const rows = await readMessages(page, kwargs); } catch (e) { if (String(e.message).includes('expected array of rows from server')) { console.error('Response contract drift — inspect raw result and update CLI'); } else throw e; } Prevention
- Keep CLI and server versions in lockstep
- Add a debug flag that dumps dispatchEvaluateResult output
- Handle error-object payloads inside dispatchEvaluateResult instead of letting them leak
When it happens
Trigger: Running message-read when the endpoint returns an object envelope (e.g. {messages: [...]}) or an error object instead of a bare array; a degraded threads enrichment path returning unexpected shape.
Common situations: Server upgrade changed the response shape; auth failure returned an error payload that leaked through dispatchEvaluateResult; middlewares/proxies wrapping the array.
Understand the failure class
Background: Schema validation failed / invalid input schema: payload rejected because its shape doesn't match the expected schema — this error's family across 28 libraries.
Related errors
- expected files array, got ${typeof files} (contract drift?)
- expected array of rows from server, got ${typeof rows} (cont
- expected inbox items array, got ${typeof items} (contract dr
- expected array of rows from server, got ${typeof rows} (cont
- workspace/create returned no workspace_id: ${JSON.stringify(
AI-assisted analysis of jackwener/OpenCLI@49907e53dc (2026-08-29).
Data as JSON: /api/errors/86b9aea248575f0b.
Report an issue: GitHub.