{"record":{"id":"8ab791ea44e7df0f","repo":"jackwener/OpenCLI","slug":"gemini-model-discovery-returned-a-malformed-browse","errorCode":null,"errorMessage":"Gemini model discovery returned a malformed Browser Bridge envelope","messagePattern":"Gemini model discovery returned a malformed Browser Bridge envelope","errorType":"exception","errorClass":"CommandExecutionError","httpStatus":null,"severity":"error","filePath":"clis/gemini/ask.js","lineNumber":31,"sourceCode":"  waitForGeminiSubmission,\n} from './utils.js';\nimport { pickModelPickerScript, readMenuModelsScript } from './models.js';\nfunction normalizeBooleanFlag(value) {\n    if (typeof value === 'boolean')\n        return value;\n    const normalized = String(value ?? '').trim().toLowerCase();\n    return normalized === 'true' || normalized === '1' || normalized === 'yes' || normalized === 'on';\n}\nconst NO_RESPONSE_PREFIX = '[NO RESPONSE]';\n\n/**\n * Validate a --model value for gemini ask.\n * Throws ArgumentError for short aliases or invalid formats.\n */\nfunction unwrapBrowserBridgeEnvelope(value) {\n    if (value && typeof value === 'object' && !Array.isArray(value) && 'session' in value) {\n        if ('data' in value) return value.data;\n        throw new CommandExecutionError('Gemini model discovery returned a malformed Browser Bridge envelope');\n    }\n    return value;\n}\n\nfunction requireDiscoveredModels(value) {\n    const unwrapped = unwrapBrowserBridgeEnvelope(value);\n    if (!Array.isArray(unwrapped)) {\n        throw new CommandExecutionError('Gemini model discovery returned a malformed result');\n    }\n    for (const row of unwrapped) {\n        if (!row || typeof row.model !== 'string' || !Array.isArray(row.thinkingValues)) {\n            throw new CommandExecutionError('Gemini model discovery returned a malformed row');\n        }\n    }\n    return unwrapped;\n}\n\nfunction validateAskModelValue(value) {","sourceCodeStart":13,"sourceCodeEnd":49,"githubUrl":"https://github.com/jackwener/OpenCLI/blob/49907e53dc3ade5c223ff0c4c2c2785687cec4e6/clis/gemini/ask.js#L13-L49","documentation":"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.","triggerScenarios":"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`.","commonSituations":"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.","solutions":["Retry the command — a transient race in the bridge often resolves on a second run","Run `opencli gemini models` to test discovery in isolation and confirm whether the bridge is consistently broken","Update opencli to a version compatible with the current Gemini model-discovery UI"],"exampleFix":"// before\nif ('data' in value) return value.data;\nthrow new CommandExecutionError('Gemini model discovery returned a malformed Browser Bridge envelope');\n// after\nif ('data' in value) return value.data;\nawait new Promise(r => setTimeout(r, 1000)); // allow discovery to settle, then retry unwrap once\nif ('data' in value) return value.data;\nthrow new CommandExecutionError('Gemini model discovery returned a malformed Browser Bridge envelope');","handlingStrategy":"retry","validationCode":"function looksLikeBridgeEnvelope(v) {\n  return v && typeof v === 'object' && !Array.isArray(v) && 'session' in v;\n}","typeGuard":"function hasEnvelopeData(value) {\n  return typeof value === 'object' && value !== null && 'session' in value && 'data' in value;\n}","tryCatchPattern":"try {\n  const models = await geminiAsk(args);\n} catch (err) {\n  if (err.message.includes('malformed Browser Bridge envelope')) {\n    await sleep(1500); // let discovery settle\n    return geminiAsk(args); // retry once\n  }\n  throw err;\n}","preventionTips":["Retry once with a delay before giving up","Test discovery via `opencli gemini models` first","Keep opencli updated when the Gemini UI changes","Ensure the browser page is fully loaded before automation runs"],"tags":["browser-automation","envelope","gemini"],"backgroundTag":"malformed-response-envelope","analyzedSha":"49907e53dc3ade5c223ff0c4c2c2785687cec4e6","analyzedAt":"2026-08-29T08:14:47.543Z","schemaVersion":2},"datasetVersion":"2026-08-29T12:17:43.993Z"}