{"record":{"id":"6b2ce177eb0339dd","repo":"jackwener/OpenCLI","slug":"repeat-must-be-a-positive-integer","errorCode":null,"errorMessage":"--repeat must be a positive integer","messagePattern":"--repeat must be a positive integer","errorType":"validation","errorClass":"ArgumentError","httpStatus":null,"severity":"error","filePath":"clis/midjourney/capabilities.js","lineNumber":236,"sourceCode":"  if (promptHasFlag(prompt, ['video', 'loop'])\n    || promptParamValue(prompt, ['video', 'bs', 'motion', 'end'])) {\n    throw new ArgumentError('Video parameters are not accepted by generate; create an image first, then use `midjourney action`');\n  }\n  const quality = promptParamValue(prompt, ['q', 'quality']);\n  if (quality && ['v8.1', 'v8.2'].includes(selectedModel)) {\n    throw new ArgumentError(`--quality is not supported by ${selectedModel}`);\n  }\n  if (quality) {\n    const normalizedQuality = Number(quality);\n    if (![0.25, 0.5, 1].includes(normalizedQuality)) {\n      throw new ArgumentError('--quality must be 0.25, 0.5, or 1 for supported legacy models');\n    }\n  }\n\n  const rawRepeat = promptParamValue(prompt, ['r', 'repeat']);\n  const structuredRepeat = args.repeat == null || args.repeat === '' ? null : Number(args.repeat);\n  if (structuredRepeat != null && (!Number.isInteger(structuredRepeat) || structuredRepeat < 1)) {\n    throw new ArgumentError('--repeat must be a positive integer');\n  }\n  if (rawRepeat != null && (!/^\\d+$/.test(rawRepeat) || Number(rawRepeat) < 1)) {\n    throw new ArgumentError('--repeat in the prompt must be a positive integer');\n  }\n  if (structuredRepeat != null && rawRepeat != null && structuredRepeat !== Number(rawRepeat)) {\n    throw new ArgumentError(`--repeat conflicts with the prompt (${structuredRepeat} vs ${rawRepeat})`);\n  }\n  const repeat = structuredRepeat ?? (rawRepeat == null ? 1 : Number(rawRepeat));\n  if (repeat > capabilities.repeatLimit) {\n    throw new ArgumentError(`${capabilities.plan || 'current'} plan allows at most ${capabilities.repeatLimit} repeat/permutation jobs`);\n  }\n\n  let perJobMinutes = hasOmniReference || promptHasFlag(prompt, ['oref'])\n    ? GPU_COST_MINUTES.omni\n    : resolution === 'hd'\n      ? GPU_COST_MINUTES.imageHd\n      : GPU_COST_MINUTES.imageSd;\n  if (promptHasFlag(prompt, ['draft'])) perJobMinutes /= 2;","sourceCodeStart":218,"sourceCodeEnd":254,"githubUrl":"https://github.com/jackwener/OpenCLI/blob/49907e53dc3ade5c223ff0c4c2c2785687cec4e6/clis/midjourney/capabilities.js#L218-L254","documentation":"resolveGenerationPlan() validates the repeat count for Midjourney generation from two places: the structured args (--repeat CLI flag) and the raw prompt parameter (r/repeat). It throws this ArgumentError when the structured --repeat value is present but is not an integer >= 1 — e.g. 0, negative numbers, or non-integer values like '2.5' or 'abc'.","triggerScenarios":"Calling plan()/generation with args.repeat set to something that Number()-coerces to a non-integer or a value < 1 — e.g. --repeat 0, --repeat -2, --repeat 2.5, --repeat abc. (Empty string is treated as unset and skipped.)","commonSituations":"Shell scripts templating --repeat with an unset variable defaulting to 0; users confusing 0-indexed counts; passing fractional values copied from docs; typo like --repeat 1.5.","solutions":["Pass a positive integer: --repeat 4 instead of 0, -1, or a fraction.","If the value comes from a variable/script, default and validate it before invoking, e.g. REPEAT=${REPEAT:-1}.","Put the repeat in the prompt as `--r 4` instead if the structured flag is problematic, keeping values consistent.","Remove the --repeat flag entirely to use the default count."],"exampleFix":"// before\nnode mj.js plan --prompt \"sunset --r 2\" --repeat 0\n// after\nnode mj.js plan --prompt \"sunset --r 2\" --repeat 2","handlingStrategy":"validation","validationCode":"const repeat = Number(process.env.REPEAT ?? 1);\nif (!Number.isInteger(repeat) || repeat < 1) {\n  throw new Error(`REPEAT must be a positive integer, got: ${process.env.REPEAT}`);\n}\n// then pass --repeat ${repeat}","typeGuard":"function isValidRepeat(v) {\n  const n = Number(v);\n  return v != null && v !== '' && Number.isInteger(n) && n >= 1;\n}","tryCatchPattern":"try {\n  const plan = await midjourney.plan({ prompt, repeat: repeatArg });\n} catch (err) {\n  if (err instanceof ArgumentError && /--repeat must be a positive integer/.test(err.message)) {\n    repeatArg = 1; // fall back to default and retry\n  } else throw err;\n}","preventionTips":["Validate repeat values with Number.isInteger(v) && v >= 1 before calling the API.","Default unset variables in shell scripts: REPEAT=${REPEAT:-1}.","If specifying repeat in both the prompt (--r N) and the flag, keep the values identical to avoid the conflict error.","Avoid fractional or zero counts; repeat is a count of generations, not an index."],"tags":["argument-validation","cli","midjourney"],"backgroundTag":"invalid-argument-value","analyzedSha":"49907e53dc3ade5c223ff0c4c2c2785687cec4e6","analyzedAt":"2026-08-29T08:14:47.543Z","schemaVersion":2},"datasetVersion":"2026-08-29T12:17:43.993Z"}