{"record":{"id":"bd1eaff4223fa1ac","repo":"jackwener/OpenCLI","slug":"label-must-be-a-positive-integer-bd1eaf","errorCode":null,"errorMessage":"${label} must be a positive integer","messagePattern":"(.+?) must be a positive integer","errorType":"validation","errorClass":"ArgumentError","httpStatus":null,"severity":"error","filePath":"clis/suno/utils.js","lineNumber":88,"sourceCode":"\nexport function normalizeBooleanFlag(value, fallback = false) {\n    if (typeof value === 'boolean') return value;\n    if (value === null || value === undefined || value === '') return fallback;\n    const s = String(value).trim().toLowerCase();\n    return s === 'true' || s === '1' || s === 'yes' || s === 'on';\n}\n\nexport function unwrapEvaluateResult(value) {\n    if (value && typeof value === 'object' && 'session' in value && 'data' in value) {\n        return value.data;\n    }\n    return value;\n}\n\nexport function requirePositiveInt(value, label) {\n    const n = Number(value);\n    if (!Number.isInteger(n) || n < 1) {\n        throw new ArgumentError(`${label} must be a positive integer`);\n    }\n    return n;\n}\n\nexport function requireNonNegativeInt(value, label) {\n    const n = Number(value);\n    if (!Number.isInteger(n) || n < 0) {\n        throw new ArgumentError(`${label} must be a non-negative integer`);\n    }\n    return n;\n}\n\nexport function clampSlider(value, label, def) {\n    if (value === undefined || value === null || value === '') return def;\n    const n = Number(value);\n    if (!Number.isFinite(n) || n < 0 || n > 1) {\n        throw new ArgumentError(`${label} must be a number between 0 and 1`);\n    }","sourceCodeStart":70,"sourceCodeEnd":106,"githubUrl":"https://github.com/jackwener/OpenCLI/blob/49907e53dc3ade5c223ff0c4c2c2785687cec4e6/clis/suno/utils.js#L70-L106","documentation":"requirePositiveInt coerces its input with Number() and requires an integer >= 1, throwing ArgumentError with the given label otherwise. It backs the `--timeout` and `--limit` options, so any non-integer, NaN, or <1 value fails fast before any Suno request.","triggerScenarios":"Passing `--timeout 0`, `--limit -5`, `--timeout abc`, `--limit 2.5`, or an empty-string value that coerces to NaN/0 for any option routed through requirePositiveInt (timeout, limit).","commonSituations":"Typing fractional or zero values; shell quoting issues producing empty strings; copying examples with units like `--timeout 30s` (coerces to NaN); using negative numbers intending 'unlimited'.","solutions":["Pass a whole number >= 1, e.g. `--timeout 30 --limit 10`.","Strip units from the value (`30s` → `30`).","Check the label in the message to see which flag is offending.","Quote the value in your shell if it contains characters that break argument parsing."],"exampleFix":"// before\nopencli suno list --limit 0\n// after\nopencli suno list --limit 10","handlingStrategy":"validation","validationCode":"function isPositiveInt(v) { const n = Number(v); return Number.isInteger(n) && n >= 1; }\nif (!isPositiveInt(limit)) throw new Error('--limit must be a positive integer');","typeGuard":"function isPositiveInt(v) {\n  const n = Number(v);\n  return Number.isFinite(n) && Number.isInteger(n) && n >= 1;\n}","tryCatchPattern":"try {\n  await run({ limit: requirePositiveInt(rawLimit, 'limit') });\n} catch (err) {\n  if (err.name === 'ArgumentError' && /must be a positive integer/.test(err.message)) {\n    limit = 10; // sensible default\n  } else throw err;\n}","preventionTips":["Pass whole numbers >= 1; never 0 or negatives.","Strip units ('30s' → 30) before passing.","Guard shell-interpolated variables with defaults (${LIMIT:-10}).","Validate user input at the CLI boundary before invoking commands."],"tags":["cli","argument-validation","input-validation"],"backgroundTag":"invalid-argument-value","analyzedSha":"49907e53dc3ade5c223ff0c4c2c2785687cec4e6","analyzedAt":"2026-08-29T08:14:47.543Z","schemaVersion":2},"datasetVersion":"2026-08-29T12:17:43.993Z"}