{"record":{"id":"224d016f8d8334f4","repo":"jackwener/OpenCLI","slug":"timeout-must-be-an-integer-from-1-to-180","errorCode":null,"errorMessage":"--timeout must be an integer from 1 to 180","messagePattern":"--timeout must be an integer from 1 to 180","errorType":"validation","errorClass":"ArgumentError","httpStatus":null,"severity":"error","filePath":"clis/midjourney/describe.js","lineNumber":38,"sourceCode":"  domain: 'www.midjourney.com',\n  strategy: Strategy.UI,\n  browser: true,\n  siteSession: 'persistent',\n  navigateBefore: MIDJOURNEY_IMAGINE_URL,\n  defaultWindowMode: 'background',\n  args: [\n    { name: 'image', positional: true, required: true, help: 'Local PNG, JPEG, WEBP, or GIF (10MB maximum)' },\n    { name: 'timeout', type: 'int', default: 60, help: 'Maximum seconds to wait for four suggestions' },\n  ],\n  columns: ['rank', 'prompt', 'source', 'created_at'],\n  func: async (page, kwargs) => {\n    await getMidjourneyAccount(page);\n    const refs = parseReferenceArgument(kwargs.image, 'image', { multiple: false });\n    if (refs[0]?.kind !== 'local') throw new ArgumentError('describe currently requires a local image file');\n    await validateLocalReferences(refs, 'image');\n    const timeout = Number(kwargs.timeout ?? 60);\n    if (!Number.isInteger(timeout) || timeout < 1 || timeout > 180) {\n      throw new ArgumentError('--timeout must be an integer from 1 to 180');\n    }\n\n    if (await isSettingsPanelVisible(page)) await toggleSettingsPanel(page);\n\n    const [sourceUrl] = await uploadReferenceLibrary(page, [refs[0].value]);\n    const baselineGroups = await page.evaluate(() => {\n      const visible = (node) => {\n        const rect = node.getBoundingClientRect();\n        return rect.width > 0 && rect.height > 0;\n      };\n      const groups = [];\n      const markers = [...document.querySelectorAll('div')]\n        .filter((node) => node.children.length === 0 && node.textContent?.trim() === 'Describe' && visible(node));\n      for (const marker of markers) {\n        let root = marker.parentElement;\n        for (let depth = 0; depth < 16 && root; depth += 1, root = root.parentElement) {\n          const prompts = [...root.querySelectorAll('p')]\n            .filter(visible)","sourceCodeStart":20,"sourceCodeEnd":56,"githubUrl":"https://github.com/jackwener/OpenCLI/blob/49907e53dc3ade5c223ff0c4c2c2785687cec4e6/clis/midjourney/describe.js#L20-L56","documentation":"describe validates its --timeout option: it must be an integer between 1 and 180 seconds (default 60), since it bounds how long the automation waits for Midjourney to return four suggestions. Non-integers, strings, or out-of-range values throw this ArgumentError.","triggerScenarios":"--timeout 0, --timeout 200, --timeout 'two minutes', or a float like 1.5 reaching the Number() coercion and integer/range check in describe's func.","commonSituations":"Users wanting 'no timeout' and passing 0 or a huge number; unit confusion (minutes vs seconds); shells quoting values so '60s' is passed instead of 60.","solutions":["Pass an integer between 1 and 180 (seconds), e.g. --timeout 120","Omit the flag to use the default of 60","Clamp the value in a wrapper: Math.min(180, Math.max(1, Math.round(Number(v))))","If more than 180s is genuinely needed, raise the limit in describe.js"],"exampleFix":"// before\nopencli midjourney describe --image ./pic.png --timeout 300\n// after\nopencli midjourney describe --image ./pic.png --timeout 180","handlingStrategy":"validation","validationCode":"const t = Number(kwargs.timeout ?? 60);\nif (!Number.isInteger(t) || t < 1 || t > 180) {\n  throw new Error(`--timeout must be an integer from 1 to 180, got ${kwargs.timeout}`);\n}\nawait describeCommand.func(page, { ...kwargs, timeout: t });","typeGuard":"function isValidTimeout(v) {\n  return Number.isInteger(v) && v >= 1 && v <= 180;\n}","tryCatchPattern":"try {\n  await describe(page, kwargs);\n} catch (err) {\n  if (err instanceof ArgumentError && err.message.includes('--timeout')) {\n    console.error('Set --timeout to an integer between 1 and 180 seconds');\n  } else throw err;\n}","preventionTips":["Clamp: Math.min(180, Math.max(1, Math.round(Number(v))))","Remember the unit is seconds, not minutes","Reject non-numeric strings at the parser level","Omit the flag to accept the 60s default"],"tags":["argument-error","validation","timeout","cli"],"backgroundTag":"invalid-argument-value","analyzedSha":"49907e53dc3ade5c223ff0c4c2c2785687cec4e6","analyzedAt":"2026-08-29T08:14:47.543Z","schemaVersion":2},"datasetVersion":"2026-08-29T12:17:43.993Z"}