jackwener/OpenCLI · error · CommandExecutionError

${result?.reason || `Could not switch to ${panelName} panel.

Error message

${result?.reason || `Could not switch to ${panelName} panel.`}

What it means

switchToPanel dispatches a full mouse-event chain on the target panel entry inside the page and expects the injected script to return { ok: true }. When the script reports failure, the library throws CommandExecutionError using the in-page reason if provided, otherwise a generic 'Could not switch to <panel> panel.' message, plus any detail.

Source

Thrown at clis/trae-solo/_actions.js:36

    if (!entry) {
      return { ok: false, reason: 'Panel entry not found.', detail: 'wanted=' + target };
    }
    const r = entry.getBoundingClientRect();
    const init = {
      bubbles: true, cancelable: true, button: 0, buttons: 1,
      clientX: Math.round(r.left + Math.min(30, r.width / 2)),
      clientY: Math.round(r.top + Math.min(10, r.height / 2)),
    };
    entry.dispatchEvent(new PointerEvent('pointerdown', { ...init, pointerType: 'mouse' }));
    entry.dispatchEvent(new MouseEvent('mousedown', init));
    entry.dispatchEvent(new PointerEvent('pointerup', { ...init, pointerType: 'mouse' }));
    entry.dispatchEvent(new MouseEvent('mouseup', init));
    entry.dispatchEvent(new MouseEvent('click', init));
    await wait(900);
    return { ok: true };
  })()`);
    if (!result?.ok) {
        throw new CommandExecutionError(result?.reason || `Could not switch to ${panelName} panel.`, result?.detail || '');
    }
    return result;
}

// Click a target element using the full pointer-event chain. Useful for
// React + radix components that ignore plain .click().
export async function pointerClickByEval(page, selectorJsExpr) {
    return await page.evaluate(`(async () => {
    const target = ${selectorJsExpr};
    if (!target) return { ok: false, reason: 'target not found' };
    const r = target.getBoundingClientRect();
    const init = {
      bubbles: true, cancelable: true, button: 0, buttons: 1,
      clientX: Math.round(r.left + r.width / 2),
      clientY: Math.round(r.top + r.height / 2),
    };
    target.dispatchEvent(new PointerEvent('pointerdown', { ...init, pointerType: 'mouse' }));
    target.dispatchEvent(new MouseEvent('mousedown', init));

View on GitHub (pinned to 49907e53dc)

Solutions

  1. Retry after waiting for the Trae window/panels to fully render
  2. Check for open dialogs or overlays in Trae and dismiss them
  3. Verify the Trae version still matches the selectors used by this library
  4. Run the switch manually once to confirm the panel exists in your build

Example fix

// before
await switchToPanel(page, 'chat');
// after
await page.wait(2); // let UI settle
await switchToPanel(page, 'chat');
Defensive patterns

Strategy: retry

Validate before calling

const info = await page.evaluate(inspectTraeShellScript());
if (!info?.windowReady || info?.dialogOpen) throw new SkipError('Trae UI not ready; wait before switching panels');

Type guard

const isPanelSwitchOk = (r) => r && r.ok === true;

Try / catch

try { return await switchToPanel(page, panelName); } catch (e) { if (e instanceof CommandExecutionError && /Could not switch/.test(e.message)) { await page.wait(2); return switchToPanel(page, panelName); } throw e; }

Prevention

When it happens

Trigger: The panel entry element was not found or not clickable (selector drift after a Trae update), an overlay intercepted the synthetic mouse events, or the in-page script threw before returning ok.

Common situations: Trae UI updates renaming panel entries, running before the app window fully renders, or popup dialogs blocking interaction.

Related errors


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