jackwener/OpenCLI · error · CommandExecutionError

Gemini model discovery returned a malformed Browser Bridge e

Error message

Gemini model discovery returned a malformed Browser Bridge envelope

What it means

unwrapBrowserBridgeEnvelope in clis/gemini/ask.js unwraps a Browser Bridge discovery envelope: an object containing `session` and `data`. If such an object lacks `data`, the envelope is structurally incomplete and this CommandExecutionError is thrown instead of returning undefined. It protects the model picker from silently consuming a broken envelope.

Source

Thrown at clis/gemini/ask.js:31

  waitForGeminiSubmission,
} from './utils.js';
import { pickModelPickerScript, readMenuModelsScript } from './models.js';
function normalizeBooleanFlag(value) {
    if (typeof value === 'boolean')
        return value;
    const normalized = String(value ?? '').trim().toLowerCase();
    return normalized === 'true' || normalized === '1' || normalized === 'yes' || normalized === 'on';
}
const NO_RESPONSE_PREFIX = '[NO RESPONSE]';

/**
 * Validate a --model value for gemini ask.
 * Throws ArgumentError for short aliases or invalid formats.
 */
function unwrapBrowserBridgeEnvelope(value) {
    if (value && typeof value === 'object' && !Array.isArray(value) && 'session' in value) {
        if ('data' in value) return value.data;
        throw new CommandExecutionError('Gemini model discovery returned a malformed Browser Bridge envelope');
    }
    return value;
}

function requireDiscoveredModels(value) {
    const unwrapped = unwrapBrowserBridgeEnvelope(value);
    if (!Array.isArray(unwrapped)) {
        throw new CommandExecutionError('Gemini model discovery returned a malformed result');
    }
    for (const row of unwrapped) {
        if (!row || typeof row.model !== 'string' || !Array.isArray(row.thinkingValues)) {
            throw new CommandExecutionError('Gemini model discovery returned a malformed row');
        }
    }
    return unwrapped;
}

function validateAskModelValue(value) {

View on GitHub (pinned to 49907e53dc)

Solutions

  1. Retry the command — a transient race in the bridge often resolves on a second run
  2. Run `opencli gemini models` to test discovery in isolation and confirm whether the bridge is consistently broken
  3. Update opencli to a version compatible with the current Gemini model-discovery UI

Example fix

// before
if ('data' in value) return value.data;
throw new CommandExecutionError('Gemini model discovery returned a malformed Browser Bridge envelope');
// after
if ('data' in value) return value.data;
await new Promise(r => setTimeout(r, 1000)); // allow discovery to settle, then retry unwrap once
if ('data' in value) return value.data;
throw new CommandExecutionError('Gemini model discovery returned a malformed Browser Bridge envelope');
Defensive patterns

Strategy: retry

Validate before calling

function looksLikeBridgeEnvelope(v) {
  return v && typeof v === 'object' && !Array.isArray(v) && 'session' in v;
}

Type guard

function hasEnvelopeData(value) {
  return typeof value === 'object' && value !== null && 'session' in value && 'data' in value;
}

Try / catch

try {
  const models = await geminiAsk(args);
} catch (err) {
  if (err.message.includes('malformed Browser Bridge envelope')) {
    await sleep(1500); // let discovery settle
    return geminiAsk(args); // retry once
  }
  throw err;
}

Prevention

When it happens

Trigger: Model discovery returns `{ session: ... }` without a `data` key — e.g. the bridge captured the page state before discovery populated results, or the discovery script version no longer writes `data`.

Common situations: Browser Bridge automation raced ahead of page load; Gemini UI changed so discovery no longer emits `data`; using an outdated CLI against an updated Gemini web app.

Understand the failure class

Related errors


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