jackwener/OpenCLI · error · CommandExecutionError

Gmail ${operation} capture included a response without a bod

Error message

Gmail ${operation} capture included a response without a body; refusing possibly partial results

What it means

waitGmailCaptures throws this CommandExecutionError as soon as any captured /sync response arrives without a body (bodylessCaptureObserved). Rather than returning possibly partial Gmail results, the library fails fast. A bodyless entry means the response was captured but its content could not be read (e.g. truncated, redirected, or cleared before read).

Source

Thrown at clis/gmail/utils.js:337

    const matches = endpointEntries.filter((entry) => (
      typeof entry?.responsePreview === 'string' || entry?.responseBodyTruncated === true
    ));
    if (matches.length > 0) {
      await page.sleep(1);
      const settled = await page.readNetworkCapture();
      const settledEndpointEntries = (Array.isArray(settled) ? settled : [])
        .filter((entry) => String(entry?.url || '').includes(`/i/${endpoint}`));
      if (settledEndpointEntries.some((entry) => (
        typeof entry?.responsePreview !== 'string'
        && entry?.responseBodyTruncated !== true
      ))) {
        bodylessCaptureObserved = true;
      }
      matches.push(...settledEndpointEntries.filter((entry) => (
        typeof entry?.responsePreview === 'string' || entry?.responseBodyTruncated === true
      )));
      if (bodylessCaptureObserved) {
        throw new CommandExecutionError(
          `Gmail ${operation} capture included a response without a body; refusing possibly partial results`,
        );
      }
      return matches.map((entry) => parseJsonCapture(entry, operation));
    }
    await page.sleep(0.25);
  }
  if (bodylessCaptureObserved) {
    throw new CommandExecutionError(
      `Gmail ${operation} capture lost a response body; refusing possibly partial results`,
    );
  }
  throw new TimeoutError(`Gmail ${operation} capture`, timeoutSeconds, `No /${endpoint} response was observed after the Gmail action.`);
}

async function renderedLabels(page, account) {
  await page.goto(`${GMAIL_ORIGIN}/mail/u/${account}/#settings/labels`);
  await page.sleep(2);

View on GitHub (pinned to 49907e53dc)

Solutions

  1. Retry the command; transient aborted responses usually succeed on a second attempt
  2. Update the browser automation driver so response bodies are captured reliably
  3. Reduce concurrent Gmail page activity that can abort in-flight sync requests
  4. If it persists, reload Gmail and re-run, checking for extensions/service workers interfering with /sync responses
Defensive patterns

Strategy: retry

Try / catch

try {
  const threads = await queryThreads(page, 'in:unread');
} catch (e) {
  if (/response without a body/.test(e.message)) {
    // transient aborted sync response — retry once after a pause
    await page.sleep(2);
    return queryThreads(page, 'in:unread');
  }
  throw e;
}

Prevention

When it happens

Trigger: During queryThreads/fetchThread (via bodies), a settled /sync/i/{endpoint} capture entry has neither a string responsePreview nor responseBodyTruncated === true, i.e. a response arrived but carried no readable body.

Common situations: Gmail aborted/redirected a sync request mid-flight; response streaming not captured by the driver version; heavy page activity causing response buffers to be evicted; service-worker-served responses the capture hook cannot read.

Related errors


AI-assisted analysis of jackwener/OpenCLI@49907e53dc (2026-08-29). Data as JSON: /api/errors/e5a3020dce4b4104. Report an issue: GitHub.