jackwener/OpenCLI · error · CommandExecutionError
Browser Bridge download lifecycle support is required for so
Error message
Browser Bridge download lifecycle support is required for social video/GIF export
What it means
A CommandExecutionError raised when the page object lacks a waitForDownload function, meaning the connected Browser Bridge does not implement the download lifecycle API. The social/GIF export flow relies on the bridge to report when a browser-initiated download completes; without that hook it cannot reliably capture the file.
Source
Thrown at clis/midjourney/utils.js:756
const existing = await existingMedia(filePath, force, config.mime);
if (existing) return { index, kind, filePath, bytes: existing.size, url: null, mime: config.mime, cached: true };
await page.goto(jobUrl(jobId, index));
await page.wait({ selector: 'video[src]', timeout: 20 });
await page.click('button[title="Options"]');
await page.wait(0.3);
const marked = unwrapEvaluateResult(await page.evaluate((label) => {
document.querySelectorAll('[data-opencli-video-download]').forEach((node) => node.removeAttribute('data-opencli-video-download'));
const button = [...document.querySelectorAll('button[role="menuitem"],button')]
.find((node) => node.textContent?.trim() === label && node.getBoundingClientRect().width > 0);
if (!button) return false;
button.setAttribute('data-opencli-video-download', '1');
return true;
}, config.label));
if (!marked) throw new CommandExecutionError(`Midjourney did not expose "${config.label}" for video ${jobId}`);
await page.click('[data-opencli-video-download="1"]');
if (typeof page.waitForDownload !== 'function') {
throw new CommandExecutionError('Browser Bridge download lifecycle support is required for social video/GIF export');
}
const downloaded = await page.waitForDownload(jobId, 60_000);
if (!downloaded?.downloaded || downloaded.state !== 'complete' || !downloaded.filename) {
throw new CommandExecutionError(`Midjourney ${kind} download did not complete: ${downloaded?.error || downloaded?.state || 'unknown'}`);
}
const sourcePath = path.resolve(String(downloaded.filename));
const sourceStat = await fs.stat(sourcePath).catch(() => null);
if (!sourceStat?.isFile() || sourceStat.size <= 0) {
throw new CommandExecutionError(`Browser reported a completed download but the file is missing: ${sourcePath}`);
}
const handle = await fs.open(sourcePath, 'r');
let actualMime;
try {
const header = Buffer.alloc(16);
const { bytesRead } = await handle.read(header, 0, header.length, 0);
actualMime = sniffMediaMime(header.subarray(0, bytesRead));
} finally {
await handle.close();View on GitHub (pinned to 49907e53dc)
Solutions
- Upgrade the Browser Bridge client/extension to a version that implements waitForDownload(jobId, timeoutMs)
- Ensure the CLI connects through the official bridge-managed page object rather than a raw Playwright/Puppeteer page
- Pin matching versions of the CLI and bridge packages in your environment
- If you maintain a custom bridge, implement waitForDownload returning { downloaded, state, filename, mime }
Example fix
// before
const page = await playwright.chromium.launch().newPage();
await downloadRenderedVideo(page, jobId, 0, 'gif', outDir);
// after
const page = await bridge.connect({ browser: 'chromium' }); // bridge page implements waitForDownload
await downloadRenderedVideo(page, jobId, 0, 'gif', outDir); Defensive patterns
Strategy: type-guard
Validate before calling
if (typeof page?.waitForDownload !== 'function') {
throw new Error('Browser Bridge lacks waitForDownload — upgrade the bridge client before exporting social video/GIF');
}
await downloadRenderedVideo(page, jobId, i, kind, outDir); Type guard
function supportsDownloadLifecycle(page) {
return typeof page?.waitForDownload === 'function';
} Try / catch
try {
await downloadRenderedVideo(page, jobId, i, kind, outDir);
} catch (err) {
if (err.message.includes('download lifecycle support')) {
console.error('Upgrade your Browser Bridge: npm i -g @opencli/browser-bridge@latest');
} else throw err;
} Prevention
- Keep the Browser Bridge client and CLI on matching versions (pin both in CI)
- Check for waitForDownload support at startup and fail fast with a clear upgrade message
- Avoid passing raw Playwright/Puppeteer pages where a bridge-managed page is expected
When it happens
Trigger: downloadRenderedVideo clicks the marked download button, then checks typeof page.waitForDownload === 'function' and it is undefined — the bridge client is an older version or a plain Playwright/Puppeteer page without the extension.
Common situations: Running an outdated opencli browser-bridge client against a newer CLI (or vice versa); using a self-built bridge that never implemented waitForDownload; pointing the CLI at a browser session not managed by the bridge.
Related errors
- Browser Bridge does not support Reference drag-and-drop
- Browser Bridge native click support is required for Creation
- Browser Bridge reported ${downloaded.mime} for ${sourcePath}
- Gmail ${label} returned a malformed Browser Bridge envelope
- Gmail ${operation} response exceeded the browser capture lim
AI-assisted analysis of jackwener/OpenCLI@49907e53dc (2026-08-29).
Data as JSON: /api/errors/a8267bbc7d4466a0.
Report an issue: GitHub.