jackwener/OpenCLI · error · ArgumentError

--timeout must be a positive integer (seconds)

Error message

--timeout must be a positive integer (seconds)

What it means

The `chatgpt image` command validates the --timeout kwarg and throws ArgumentError when it is not an integer >= 1. Since --timeout is declared as type int with default 240, this fires when a non-integer (e.g. a string like '30s' or 'abc', or a float) reaches the command body and fails Number.isInteger(timeout) || timeout < 1.

Source

Thrown at clis/chatgpt/image.js:89

    defaultFormat: 'plain',
    args: [
        { name: 'prompt', positional: true, required: true, help: 'Image prompt to send to ChatGPT' },
        { name: 'image', help: 'Local image path to attach before prompting; comma-separated paths are supported' },
        { name: 'project', valueRequired: true, help: 'Start image generation inside a ChatGPT project ID or /g/g-p-<id> URL' },
        { name: 'op', help: 'Output directory (default: ~/Pictures/chatgpt)' },
        { name: 'sd', type: 'boolean', default: false, help: 'Skip download shorthand; only show ChatGPT link' },
        { name: 'timeout', type: 'int', required: false, default: 240, help: 'Max seconds for the overall command (default: 240)' },
    ],
    columns: ['status', 'file', 'link'],
    func: async (page, kwargs) => {
        const prompt = kwargs.prompt;
        const imagePaths = parseImagePaths(kwargs.image);
        const outputDir = resolveOutputDir(kwargs.op);
        const skipDownloadRaw = kwargs.sd;
        const skipDownload = skipDownloadRaw === '' || skipDownloadRaw === true || normalizeBooleanFlag(skipDownloadRaw);
        const timeout = kwargs.timeout;
        if (!Number.isInteger(timeout) || timeout < 1) {
            throw new ArgumentError('--timeout must be a positive integer (seconds)');
        }
        const preparedImages = imagePaths.length ? await prepareChatGPTImagePaths(imagePaths) : { ok: true, paths: [] };
        if (!preparedImages.ok) {
            throw new ArgumentError(preparedImages.reason);
        }

        // Navigate with full reload to clear React sidebar state before editing the draft.
        if (kwargs.project) {
            await navigateToProject(page, kwargs.project);
        } else {
            await page.goto(`https://${CHATGPT_DOMAIN}/new`, { settleMs: 2000 });
        }
        await clearChatGPTDraft(page);

        if (imagePaths.length) {
            let upload;
            try {
                upload = await uploadChatGPTImages(page, preparedImages.paths);

View on GitHub (pinned to 49907e53dc)

Solutions

  1. Pass a plain positive integer, e.g. --timeout 240.
  2. Remove surrounding units/characters from the value ('30s' → '30').
  3. In scripts, coerce before calling: timeout = parseInt(process.env.TIMEOUT, 10) and check Number.isInteger.
  4. Omit --timeout entirely to use the 240s default.

Example fix

// before
opencli chatgpt image "a red fox" --timeout 30s
// after
opencli chatgpt image "a red fox" --timeout 30
Defensive patterns

Strategy: validation

Validate before calling

function coerceTimeout(value, fallback = 240) {
  const n = typeof value === 'number' ? value : parseInt(String(value ?? ''), 10);
  return Number.isInteger(n) && n >= 1 ? n : fallback;
}
const timeout = coerceTimeout(process.env.IMAGE_TIMEOUT ?? '240');

Type guard

function isValidTimeout(v) {
  return Number.isInteger(v) && v >= 1;
}

Try / catch

try {
  await run('chatgpt image', prompt, '--timeout', String(timeout));
} catch (err) {
  if (String(err.message).includes('--timeout must be a positive integer')) {
    return run('chatgpt image', prompt); // use the 240s default
  }
  throw err;
}

Prevention

When it happens

Trigger: Calling `opencli chatgpt image "prompt" --timeout 0`, --timeout -5, --timeout abc, --timeout 2.5, or passing an unparseable value through a wrapper that does not coerce it to int.

Common situations: Typo like `--timeout=30s`; scripts passing environment variables as strings; automation passing null/undefined explicitly; unit confusion (passing milliseconds like 60000 expecting it to work — it would pass validation but run far too long, whereas 0 or '60 sec' fails here).

Understand the failure class

Background: "Must be a positive integer", "Invalid value", "Unsupported": the invalid-argument-value error family, when a library rejects the value you pass — this error's family across 35 libraries.

Related errors


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