jackwener/OpenCLI · error · CommandExecutionError

Gmail ${label} returned a malformed Browser Bridge envelope

Error message

Gmail ${label} returned a malformed Browser Bridge envelope

What it means

unwrapBrowserResult validates that browser responses use the Browser Bridge envelope shape { session: string, data: ... }. If an object carries a `session` key but is missing `data` or has a non-string session, the envelope is malformed and the library throws CommandExecutionError rather than returning corrupt data.

Source

Thrown at clis/gmail/utils.js:22

  CommandExecutionError,
  EmptyResultError,
  TimeoutError,
} from '@jackwener/opencli/errors';

export const GMAIL_ORIGIN = 'https://mail.google.com';
export const GMAIL_HOST = 'mail.google.com';
export const DEFAULT_LIMIT = 20;
export const MAX_LIMIT = 200;
const PAGE_SIZE = 50;
const CAPTURE_WAIT_SECONDS = 10;
const MAX_BODY_CHARS = 20_000;

export function unwrapBrowserResult(value, label = 'browser probe') {
  if (value && typeof value === 'object' && !Array.isArray(value) && 'session' in value) {
    if (typeof value.session === 'string' && Object.prototype.hasOwnProperty.call(value, 'data')) {
      return value.data;
    }
    throw new CommandExecutionError(`Gmail ${label} returned a malformed Browser Bridge envelope`);
  }
  return value;
}

export function parseLimit(raw, fallback = DEFAULT_LIMIT, max = MAX_LIMIT) {
  const value = raw ?? fallback;
  const limit = Number(value);
  if (!Number.isInteger(limit) || limit <= 0) {
    throw new ArgumentError('limit must be a positive integer');
  }
  if (limit > max) {
    throw new ArgumentError(`limit must be <= ${max}`);
  }
  return limit;
}

export function parseAccount(raw) {
  const value = raw ?? 0;

View on GitHub (pinned to 49907e53dc)

Solutions

  1. Update the Browser Bridge extension and the gmail CLI to matching versions so the envelope contract ({session: string, data}) is respected.
  2. Inspect the raw value returned by the bridge to see what shape is actually being produced.
  3. Check for intermediary code that wraps or rewrites the bridge response and accidentally adds/removes a `session` or `data` key.
  4. Retry the browser request; a transient bridge failure may produce a partial envelope.

Example fix

// before (bridge v1 response, old envelope)
{ session: 'abc' } // no data -> malformed
// after: upgrade bridge so it returns
{ session: 'abc', data: { rows: [...] } }
Defensive patterns

Strategy: type-guard

Validate before calling

const isEnvelope = (v) => v && typeof v === 'object' && !Array.isArray(v) &&
  ('session' in v ? typeof v.session === 'string' && 'data' in v : true);

Type guard

function isBridgeEnvelope(v) {
  return !!v && typeof v === 'object' && !Array.isArray(v) &&
    typeof v.session === 'string' && Object.prototype.hasOwnProperty.call(v, 'data');
}

Try / catch

try {
  rows = unwrapBrowserResult(raw, 'search');
} catch (e) {
  if (/malformed Browser Bridge envelope/.test(e.message)) {
    console.error('Bridge/CLI version mismatch — update both');
  }
  throw e;
}

Prevention

When it happens

Trigger: The Browser Bridge returns an object with a `session` property but no `data` property, or session is not a string — e.g. a version mismatch between the CLI and bridge where the envelope contract changed, or the bridge returned an error object containing a session-like field.

Common situations: Upgrading the CLI without upgrading the browser bridge extension (or vice versa); a proxy/middleware rewrites the response shape; the bridge returns an error payload with a `session` field that collides with the envelope protocol.

Understand the failure class

Related errors


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