jackwener/OpenCLI · error · CommandExecutionError
Mercury reimbursement-draft requires Browser Bridge uploadFi
Error message
Mercury reimbursement-draft requires Browser Bridge uploadFiles support to verify the intended receipt input
What it means
This CommandExecutionError is thrown by the mercury reimbursement-draft command when the browser automation `page` object does not expose an `uploadFiles` method. The command needs Browser Bridge's uploadFiles capability to attach the local receipt file to the expense form's hidden file input and verify the upload result. Without it, the command cannot safely proceed and fails fast before attempting the upload.
Source
Thrown at clis/mercury/reimbursement-draft.js:60
const before = await inspectMercury(page);
assertLoggedIn(before);
await page.goto(MERCURY_EXPENSES_URL, { waitUntil: 'load', settleMs: 1500 });
await page.wait({ time: 1 });
const createSurface = await assertCreateExpenseSurface(page);
if (createSurface.hasFinalSubmit && /review/i.test(createSurface.bodyPreview || '')) {
throw new CommandExecutionError('Mercury appears to have an existing expense review open; refusing to click a possible final Submit expense button');
}
const opened = await clickCreateExpenseButton(page);
if (!opened.clicked) {
throw new CommandExecutionError('Could not find the Mercury Submit expense or New expense button');
}
await page.wait({ time: 2 });
if (!page.uploadFiles) {
throw new CommandExecutionError('Mercury reimbursement-draft requires Browser Bridge uploadFiles support to verify the intended receipt input');
}
const upload = await page.uploadFiles(RECEIPT_INPUT_SELECTOR, [input.receipt]);
if (!upload || upload.uploaded !== true || upload.files !== 1) {
throw new CommandExecutionError('Mercury receipt upload did not confirm exactly one uploaded file');
}
if (upload.target !== RECEIPT_INPUT_SELECTOR || upload.matches_n !== 1) {
throw new CommandExecutionError('Mercury receipt upload did not confirm the intended receipt input');
}
const uploadedNames = Array.isArray(upload.file_names) ? upload.file_names : [];
if (!uploadedNames.includes(receiptBasename(input.receipt))) {
throw new CommandExecutionError('Mercury receipt upload did not confirm the expected receipt file');
}
if (input.ocrWaitSeconds > 0) await page.wait({ time: input.ocrWaitSeconds });
const fields = await fillReimbursementFields(page, input);
await page.wait({ time: 1 });
const expectedFields = ['amount', 'currency', 'date', 'merchant', 'category', 'notes'];View on GitHub (pinned to 49907e53dc)
Solutions
- Update the Browser Bridge package to a version that implements `page.uploadFiles` (check for the method in the bridge changelog).
- Ensure the command is running with `browser: true` through the standard opencli Browser Bridge driver, not a custom page implementation.
- Verify the installed @jackwener/opencli and browser-bridge versions are compatible (npm ls / lockfile), then reinstall.
- If using a custom page shim, implement `uploadFiles(selector, files)` returning `{ uploaded, files, target, matches_n, file_names }`.
Example fix
// before (old bridge shim)
const page = createPageDriver({ goto, wait, evaluate });
// after
const page = createPageDriver({ goto, wait, evaluate, uploadFiles }); // Browser Bridge >= version with uploadFiles Defensive patterns
Strategy: type-guard
Validate before calling
if (typeof page.uploadFiles !== 'function') {
throw new Error('Browser driver lacks uploadFiles; update Browser Bridge');
} Type guard
function supportsUploadFiles(page) {
return typeof page?.uploadFiles === 'function';
} Try / catch
try {
await runReimbursementDraft(page, input);
} catch (e) {
if (String(e.message).includes('uploadFiles support')) {
// upgrade bridge or fall back to a driver that implements uploadFiles
} else throw e;
} Prevention
- Pin compatible versions of @jackwener/opencli and the Browser Bridge package together.
- Before scripting, assert the driver exposes uploadFiles (typeof check).
- Keep the persistent site session's bridge daemon updated with the CLI.
- Add a smoke test that calls page.uploadFiles against a dummy input.
When it happens
Trigger: Running `opencli mercury reimbursement-draft --receipt ...` against a Browser Bridge / page driver whose API does not implement `uploadFiles` — e.g. an outdated browser-bridge package, a page handle obtained from a non-Bridge driver, or a bridge version where uploadFiles was renamed or not yet added.
Common situations: Developers hit this after upgrading opencli without upgrading the Browser Bridge dependency (or vice versa), when using an alternative driver (plain Puppeteer/Playwright wrapper) that lacks the Bridge extension, or when an old persistent site session reconnects to a stale bridge build.
Related errors
- Mercury receipt upload did not confirm exactly one uploaded
- Mercury receipt upload did not confirm the intended receipt
- Mercury receipt upload did not confirm the expected receipt
- Xianyu publish requires Browser Bridge file upload support
- ChatGPT model selection requires native browser click suppor
AI-assisted analysis of jackwener/OpenCLI@49907e53dc (2026-08-29).
Data as JSON: /api/errors/2595995b179e8236.
Report an issue: GitHub.