jackwener/OpenCLI · warning · CommandExecutionError

Mercury appears to have an existing expense review open…

Error message

Mercury appears to have an existing expense review open; refusing to click a possible final Submit expense button

What it means

Before creating a Mercury reimbursement draft, the flow inspects the expenses page via assertCreateExpenseSurface. If the page already shows a final 'Submit expense' control within a review view (hasFinalSubmit plus a /review/i body preview), the automation refuses to click, since clicking could submit a pre-existing unfinished expense. It throws CommandExecutionError with this safety message.

Solutions

  1. Open the Mercury expenses page manually and complete or discard the open expense review, then rerun the command.
  2. Cancel/close the in-progress expense in the Mercury UI so the create surface is clean.
  3. Restart the browser session with a fresh page (about:blank or re-login) so no review state is carried over.
  4. If it recurs, check whether a prior automation run is leaking sessions and ensure it closes or resets the page on exit.

Example fix

// before (session reused with stale review open)
await draftReimbursement(page, {...}); // refuses: existing review open
// after
await page.goto('about:blank');
await draftReimbursement(page, {...}); // fresh create surface
Defensive patterns

Strategy: try-catch

Validate before calling

// preflight: ensure no review surface is open before automating
const body = await page.evaluate('document.body.innerText');
if (/review/i.test(body) && /submit expense/i.test(body)) {
  throw new Error('Complete or discard the open Mercury expense review first');
}

Try / catch

try {
  await draftReimbursement(page, data);
} catch (e) {
  if (/existing expense review open/.test(e.message)) {
    console.error('Resolve the open review in Mercury UI (or reset the page), then rerun');
  } else throw e;
}

Prevention

When it happens

Trigger: Running the reimbursement-draft command while Mercury already has an expense review screen open — e.g. a previous draft left mid-flow, a prior automation run crashed after opening the review, or a human left the review page open in the shared browser session.

Common situations: Retrying the command after a failed earlier run that left state behind; multiple users/automations sharing one Mercury browser profile; resuming work where the last session ended on the review step.

Related errors


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

Appendix: source

Thrown at clis/mercury/reimbursement-draft.js:49

        { name: 'currency', default: 'CNY', help: 'Original currency code' },
        { name: 'date', required: true, help: 'Expense date as YYYY-MM-DD' },
        { name: 'merchant', required: true, help: 'Merchant shown on the reimbursement' },
        { name: 'category', default: 'Marketing & Advertising', help: 'Mercury expense category' },
        { name: 'notes', required: true, help: 'Business purpose / reimbursement notes' },
        { name: 'ocr-wait-seconds', default: '8', help: 'Seconds to wait after receipt upload before correcting OCR-overwritten fields' },
        { name: 'close-after-review', type: 'boolean', default: false, help: 'Close the Review dialog after verification; final Submit is still never clicked' },
    ],
    columns: ['status', 'url', 'receipt', 'uploaded', 'fieldsTouched', 'reviewReady', 'submitBlocked', 'warnings'],
    func: async (page, kwargs) => {
        const input = normalizeReimbursementInput(kwargs);
        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');

View on GitHub (pinned to 49907e53dc)