jackwener/OpenCLI · error · CommandExecutionError
Gmail requires native browser input
Error message
Gmail ${operation} requires native browser input What it means
submitSearch requires native OS-level keyboard input: if page.nativeType is not a function it throws this CommandExecutionError. Gmail's search box ignores synthetic DOM value injection, so the library only types through the driver's native input path and refuses anything less reliable.
Solutions
- Use the library's browser page wrapper that implements nativeType
- Add/upgrade the driver bridge so page.nativeType delegates to the underlying native keyboard API (e.g. page.keyboard.type)
- Check typeof page.nativeType === 'function' before invoking Gmail search operations
- Align versions of the browser helper and this library
Example fix
// before: raw puppeteer page without nativeType const page = await browser.newPage(); await queryThreads(page, 'in:unread'); // after: adapt the driver's native keyboard into the expected API page.nativeType = (text) => page.keyboard.type(text); await queryThreads(page, 'in:unread');
Defensive patterns
Strategy: validation
Validate before calling
if (typeof page?.nativeType !== 'function') {
throw new Error('use the library page wrapper with nativeType support');
} Type guard
function supportsNativeType(page) {
return typeof page?.nativeType === 'function';
} Try / catch
try {
await queryThreads(page, 'in:inbox');
} catch (e) {
if (/requires native browser input/.test(e.message)) {
console.error('Swap in the library\'s instrumented page wrapper');
} else throw e;
} Prevention
- Obtain page objects only from the library's browser helper
- Verify nativeType exists at startup with a capability check
- Keep driver bridge versions aligned with the library
When it happens
Trigger: Calling queryThreads/listLabels with a page wrapper lacking nativeType — e.g. a raw Puppeteer Page (which has keyboard.type but not page.nativeType), a minimal shim, or an outdated browser helper.
Common situations: Handing the library a page object from a different driver/version than expected; custom page wrappers that implemented evaluate/sleep but not native input; driver upgrades that renamed the native-type helper.
Related errors
- Gmail could not set the search query exactly
- Gmail requires browser response interception
- Gmail requires native browser keyboard input
- Failed to insert text into Gemini composer
- Gmail capture
AI-assisted analysis of jackwener/OpenCLI@49907e53dc (2026-08-29).
Data as JSON: /api/errors/9ba46361d17e87fe.
Report an issue: GitHub.
Appendix: source
Thrown at clis/gmail/utils.js:463
...row,
threadId: cleanString(target).replace(/^#/, ''),
date: parsedDate && !Number.isNaN(parsedDate.getTime()) ? parsedDate.toISOString() : null,
body: cleanString(row.body).slice(0, MAX_BODY_CHARS) || null,
};
}).map(({ dateText: _dateText, ...row }) => row);
}
async function submitSearch(page, query, operation) {
const prepared = unwrapBrowserResult(await page.evaluate(`() => {
const field = document.querySelector('input[name="q"]');
if (!field) return false;
field.focus();
field.select();
return true;
}`), `${operation} search preparation`);
if (prepared !== true) throw new CommandExecutionError(`Gmail ${operation} could not find the search input`);
if (typeof page.nativeType !== 'function') {
throw new CommandExecutionError(`Gmail ${operation} requires native browser input`);
}
await page.nativeType(query);
const actual = unwrapBrowserResult(await page.evaluate(`() => document.querySelector('input[name="q"]')?.value || ''`), `${operation} search input verification`);
if (actual !== query) throw new CommandExecutionError(`Gmail ${operation} could not set the search query exactly`);
if (typeof page.cdp === 'function') {
const key = { key: 'Enter', code: 'Enter', windowsVirtualKeyCode: 13, nativeVirtualKeyCode: 13 };
await page.cdp('Input.dispatchKeyEvent', { type: 'rawKeyDown', ...key });
await page.cdp('Input.dispatchKeyEvent', { type: 'keyUp', ...key });
} else if (typeof page.nativeKeyPress === 'function') {
await page.nativeKeyPress('Enter');
} else {
throw new CommandExecutionError(`Gmail ${operation} requires native browser keyboard input`);
}
}
export async function queryThreads(page, query, { account = 0, limit = DEFAULT_LIMIT } = {}) {
const normalizedQuery = cleanString(query);
if (!normalizedQuery) throw new ArgumentError('Gmail search query cannot be empty');View on GitHub (pinned to 49907e53dc)