jackwener/OpenCLI · error · CommandExecutionError
Gmail batch-view response had an unexpected shape
Error message
Gmail batch-view response had an unexpected shape
What it means
parseBatchView validates that the Gmail batch-view (/i/bv) payload is an array of exactly 19 elements before extracting thread rows from body[2]. If the captured body is an array of any other length (or not an array), it throws this CommandExecutionError because the batch-view wire format it knows has changed or the wrong response was captured. It signals a structural mismatch, not bad user input.
Source
Thrown at clis/gmail/utils.js:135
if (!Array.isArray(value)) return null;
const address = cleanString(value[1]);
if (!address.includes('@')) return null;
return { address, name: cleanString(value[2]) || null };
}
function senderFromSummary(message) {
return addressRef(Array.isArray(message) ? message[1] : null);
}
function labelIdsFromMessages(messages) {
return [...new Set((Array.isArray(messages) ? messages : [])
.flatMap((message) => Array.isArray(message?.[10]) ? message[10] : [])
.filter((label) => typeof label === 'string' && label.startsWith('^')))];
}
export function parseBatchView(body) {
if (!Array.isArray(body) || body.length !== 19) {
throw new CommandExecutionError('Gmail batch-view response had an unexpected shape');
}
const rows = Array.isArray(body[2]) ? body[2] : [];
return rows.map((wrapper, index) => {
const record = Array.isArray(wrapper?.[0]) ? wrapper[0] : null;
if (!record || record.length < 5) {
throw new CommandExecutionError(`Gmail batch-view returned a malformed thread at index ${index}`);
}
const threadId = cleanString(record[3]).replace(/^#/, '');
const messages = Array.isArray(record[4]) ? record[4] : [];
const latest = messages.at(-1);
const sender = senderFromSummary(latest);
if (!threadId) throw new CommandExecutionError(`Gmail batch-view returned a thread without an id at index ${index}`);
const labels = labelIdsFromMessages(messages);
return {
threadId,
subject: cleanString(record[0]) || '(no subject)',
from: sender?.address || null,
fromName: sender?.name || null,View on GitHub (pinned to 49907e53dc)
Solutions
- Retry the command; if it persists, capture the raw payload and report it — the parser needs updating for the new shape.
- Update opencli to the latest version so parseBatchView matches the current Gmail wire format.
- Verify the captured page is the normal Gmail mail view (not settings/offline), then rerun.
- Clear Gmail's cache/cookies and reload to rule out stale app bundles serving a different shape.
Defensive patterns
Strategy: try-catch
Validate before calling
null
Type guard
function isBatchViewEnvelope(body) {
return Array.isArray(body) && body.length === 19 && Array.isArray(body[2]);
} Try / catch
try {
threads = await gmailSearch(query);
} catch (error) {
if (String(error.message).includes('unexpected shape')) {
reportToVendor('gmail batch-view payload shape changed', error);
// fallback: narrow the query and retry once
threads = await gmailSearch(query + ' newer_than:90d');
} else throw error;
} Prevention
- Pin/update the CLI version alongside Gmail web-app rollouts; shape errors mean the wire format moved.
- Don't run other Gmail actions in the same tab during a search capture window.
- Treat first occurrence as transient (retry), persistent occurrence as a parser-update requirement.
- Keep the browser profile's Gmail app bundle fresh (hard reload) to avoid stale shapes.
When it happens
Trigger: waitGmailCaptures hands parseBatchView a body that is not an array or whose length !== 19 — e.g. Gmail's batch-view protocol changed, a different /sync response matched the /i/bv filter, or a partial/garbage payload was captured.
Common situations: Gmail web-app rollout changing the bv payload shape, capturing a non-list response (e.g. settings or a different sync channel) that shares the /i/bv URL, future Gmail versions.
Related errors
- Gmail fetch-data response had an unexpected shape
- eastmoney convertible returned malformed diff data
- Flomo API returned a malformed memo entry
- Gmail ${operation} response exceeded the browser capture lim
- Gmail ${operation} response body was unavailable
AI-assisted analysis of jackwener/OpenCLI@49907e53dc (2026-08-29).
Data as JSON: /api/errors/96c51f0cdb6e822d.
Report an issue: GitHub.