{"record":{"id":"0176285d22f82b0e","repo":"jackwener/OpenCLI","slug":"label-must-be-an-integer-between-min-and-m","errorCode":null,"errorMessage":"${label} must be an integer between ${min} and ${max}, got ${JSON.stringify(value)}","messagePattern":"(.+?) must be an integer between (.+?) and (.+?), got (.+?)","errorType":"validation","errorClass":"ArgumentError","httpStatus":null,"severity":"error","filePath":"clis/_shared/search-adapter.js","lineNumber":15,"sourceCode":"import { ArgumentError, CommandExecutionError, EmptyResultError } from '@jackwener/opencli/errors';\n\nexport function requireSearchQuery(value, label = 'keyword') {\n  const query = String(value ?? '').trim();\n  if (!query) {\n    throw new ArgumentError(`${label} cannot be empty`);\n  }\n  return query;\n}\n\nexport function requireBoundedInteger(value, defaultValue, min, max, label) {\n  const raw = value ?? defaultValue;\n  const parsed = typeof raw === 'number' ? raw : Number(raw);\n  if (!Number.isInteger(parsed)) {\n    throw new ArgumentError(`${label} must be an integer between ${min} and ${max}, got ${JSON.stringify(value)}`);\n  }\n  if (parsed < min || parsed > max) {\n    throw new ArgumentError(`${label} must be between ${min} and ${max}, got ${parsed}`);\n  }\n  return parsed;\n}\n\nexport function requireNonNegativeInteger(value, defaultValue, label) {\n  const raw = value ?? defaultValue;\n  const parsed = typeof raw === 'number' ? raw : Number(raw);\n  if (!Number.isInteger(parsed) || parsed < 0) {\n    throw new ArgumentError(`${label} must be a non-negative integer, got ${JSON.stringify(value)}`);\n  }\n  return parsed;\n}\n\nexport function unwrapBrowserResult(value) {\n  if (value && typeof value === 'object' && !Array.isArray(value) && 'session' in value && 'data' in value) {","sourceCodeStart":1,"sourceCodeEnd":33,"githubUrl":"https://github.com/jackwener/OpenCLI/blob/49907e53dc3ade5c223ff0c4c2c2785687cec4e6/clis/_shared/search-adapter.js#L1-L33","documentation":"requireBoundedInteger coerces its input to a number (falling back to a default when nullish) and requires an integer. If the coerced value is NaN, fractional, or otherwise not an integer, it throws ArgumentError '<label> must be an integer between <min> and <max>, got <JSON of value>'.","triggerScenarios":"Passing a non-numeric string ('abc', '10px'), a fractional number (2.5), NaN, a boolean, or an object/array as the limit-related option (e.g. --limit, --max-results).","commonSituations":"String CLI args with units or whitespace ('50 results') not parsed by Number; JSON config supplying floats; environment variables containing commas ('1,000'); undefined handled fine (default applies) but empty string '' coerces to NaN and fails.","solutions":["Pass a plain integer (or numeric string) within [min, max], e.g. 50 not '50 results' or '1,000'.","Strip units/thousands separators and call Number(value) yourself, checking Number.isInteger before invoking.","Fix the config/schema so the field is typed as an integer; rely on the default by passing null/undefined rather than ''."],"exampleFix":"// before\nrequireBoundedInteger('1,000', 25, 1, 100, 'limit')  // NaN -> throws\n// after\nrequireBoundedInteger(1000, 25, 1, 100, 'limit')     // still range-checked, or use 100\n// or sanitize:\nrequireBoundedInteger(parseInt(raw.replace(/[,.]/g, ''), 10), 25, 1, 100, 'limit')","handlingStrategy":"type-guard","validationCode":"const n = Number(raw);\nif (!Number.isInteger(n)) throw new Error(`${label} must be an integer, got: ${JSON.stringify(raw)}`);","typeGuard":"const isInt = (v) => typeof v === 'number' && Number.isInteger(v);\nconst isIntLike = (v) => isInt(v) || (typeof v === 'string' && /^-?\\d+$/.test(v.trim()));","tryCatchPattern":"try {\n  const limit = requireBoundedInteger(raw, 25, 1, 100, 'limit');\n} catch (err) {\n  if (err.name === 'ArgumentError' && err.message.includes('must be an integer')) {\n    console.error(`--limit must be a whole number in range; got ${err.message}`);\n  }\n  throw err;\n}","preventionTips":["Strip units/thousand separators ('1,000 results') before numeric conversion.","Type limit fields as integers in config schemas; never pass '' (coerces to NaN).","Use Number.parseInt for strings and verify Number.isInteger afterwards."],"tags":["validation","type-error","argument-validation","cli"],"backgroundTag":"invalid-argument-type","analyzedSha":"49907e53dc3ade5c223ff0c4c2c2785687cec4e6","analyzedAt":"2026-08-29T08:14:47.543Z","schemaVersion":2},"datasetVersion":"2026-08-29T12:17:43.993Z"}