jackwener/OpenCLI · warning · CommandExecutionError

Mercury appears to have an existing expense review open; ref

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.

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)

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.