jackwener/OpenCLI · error · ArgumentError

--timeout must be a positive integer (seconds)

Error message

--timeout must be a positive integer (seconds)

What it means

The cursor `ask` command sends a prompt to the Cursor chat page in a browser session and requires an explicit --timeout in whole seconds. If kwargs.timeout is not an integer >= 1 (missing, fractional, zero, negative, or a non-number), it throws ArgumentError '--timeout must be a positive integer (seconds)' before touching the page, so a bad timeout cannot cause an infinite or zero-length wait.

Source

Thrown at clis/cursor/ask.js:20

import { ArgumentError, selectorError } from '@jackwener/opencli/errors';
export const askCommand = cli({
    site: 'cursor',
    name: 'ask',
    access: 'write',
    description: 'Send a prompt and wait for the AI response (send + wait + read)',
    domain: 'localhost',
    strategy: Strategy.UI,
    browser: true,
    args: [
        { name: 'text', required: true, positional: true, help: 'Prompt to send' },
        { name: 'timeout', type: 'int', required: false, help: 'Max seconds to wait for response (default: 30)', default: 30 },
    ],
    columns: ['Role', 'Text'],
    func: async (page, kwargs) => {
        const text = kwargs.text;
        const timeout = kwargs.timeout;
        if (!Number.isInteger(timeout) || timeout < 1) {
            throw new ArgumentError('--timeout must be a positive integer (seconds)');
        }
        // Count existing messages before sending
        const beforeCount = await page.evaluate(`
      document.querySelectorAll('[data-message-role]').length
    `);
        // Inject text into the active editor and submit
        const injected = await page.evaluate(`(function(text) {
        let editor = document.querySelector('.aislash-editor-input, [data-lexical-editor="true"], [contenteditable="true"]');
        if (!editor) return false;
        editor.focus();
        document.execCommand('insertText', false, text);
        return true;
      })(${JSON.stringify(text)})`);
        if (!injected)
            throw selectorError('Cursor input element');
        await page.wait(0.5);
        await page.pressKey('Enter');
        // Poll until a new assistant message appears or timeout

View on GitHub (pinned to 49907e53dc)

Solutions

  1. Pass --timeout as a positive integer of seconds, e.g. --timeout 30.
  2. Convert and validate before invoking: Number.isInteger(Number(raw)) && Number(raw) >= 1.
  3. Round or floor fractional values: Math.max(1, Math.round(seconds)).
  4. Do not pass 0 or negatives to mean 'no timeout'; choose a finite positive value.

Example fix

// before
cursor ask --text "hi" --timeout 2.5
// after
cursor ask --text "hi" --timeout 3
Defensive patterns

Strategy: validation

Validate before calling

const timeout = Number(rawTimeout);
if (!Number.isInteger(timeout) || timeout < 1) {
  throw new Error('--timeout must be a positive integer (seconds)');
}

Type guard

const isValidTimeout = (v) => Number.isInteger(v) && v >= 1;

Try / catch

try {
  await ask(page, { text, timeout });
} catch (e) {
  if (e instanceof ArgumentError && e.message.includes('--timeout')) {
    console.error('Pass e.g. --timeout 30 (whole seconds).');
  } else throw e;
}

Prevention

When it happens

Trigger: Calling the ask command with --timeout omitted (undefined), --timeout 0, --timeout -5, --timeout 2.5, or a string like '10' that was never converted to a number.

Common situations: Users expecting a default timeout and omitting the flag, passing decimal seconds assuming milliseconds are allowed, or scripts forwarding CLI strings without numeric parsing.

Understand the failure class

Background: "Unknown argument", "Invalid value", and "must be one of": invalid CLI argument errors explained — this error's family across 35 libraries.

Related errors


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