{"record":{"id":"5fbc60f9f14a7474","repo":"jackwener/OpenCLI","slug":"name-must-be-a-positive-integer","errorCode":null,"errorMessage":"${name} must be a positive integer","messagePattern":"(.+?) must be a positive integer","errorType":"validation","errorClass":"ArgumentError","httpStatus":null,"severity":"error","filePath":"clis/pinterest/utils.js","lineNumber":30,"sourceCode":"\n/** Resource actions that mutate; only these treat a 403 as \"you need to log in\". */\nconst WRITE_ACTIONS = new Set(['create', 'update', 'delete']);\n\n/** Unwrap the { session, data } envelope some browser-bridge versions add. */\nexport function unwrapEvaluateResult(payload) {\n  const isEnvelope = payload\n    && typeof payload === 'object'\n    && !Array.isArray(payload)\n    && 'session' in payload\n    && 'data' in payload;\n  return isEnvelope ? payload.data : payload;\n}\n\n/** Validate a positive-integer limit (throws instead of silently clamping). */\nexport function requireLimit(value, { fallback, max, name = 'limit' }) {\n  const parsed = Number(value ?? fallback);\n  if (!Number.isInteger(parsed) || parsed <= 0) {\n    throw new ArgumentError(`${name} must be a positive integer`, `e.g. --${name} 10`);\n  }\n  if (max && parsed > max) {\n    throw new ArgumentError(`${name} must be <= ${max}`, `Lower --${name} to ${max} or below`);\n  }\n  return parsed;\n}\n\n/**\n * Fold a slug for comparison. Pinterest keeps non-ASCII characters in slugs (e.g.\n * `naive-café-中文`) and stores them NFC, but a pasted or keyboard-composed accent can arrive as\n * NFD, which compares unequal byte-wise.\n */\nexport function normalizeForMatch(value) {\n  return String(value ?? '').normalize('NFC').trim().toLowerCase().replace(/\\s+/g, ' ');\n}\n\n/**\n * Pinterest path prefixes that are site routes, not usernames. Without this a pin URL parses as","sourceCodeStart":12,"sourceCodeEnd":48,"githubUrl":"https://github.com/jackwener/OpenCLI/blob/49907e53dc3ade5c223ff0c4c2c2785687cec4e6/clis/pinterest/utils.js#L12-L48","documentation":"requireLimit validates that a numeric limit argument is a positive integer before it is sent to the Pinterest API. It throws this ArgumentError when the value (or its fallback) is missing, non-numeric, non-integer, or <= 0. The library throws instead of silently clamping so callers get an immediate, actionable CLI-style error.","triggerScenarios":"Calling requireLimit (via the limit helper) with e.g. limit('abc'), limit(0), limit(-5), limit(2.5), or undefined with no fallback — anything where Number(value ?? fallback) is not an integer > 0.","commonSituations":"Passing a CLI flag like --limit from a shell where it was left empty or contained a suffix ('10s'); deriving a limit from parseFloat() of user text; typos like 'lmit'; using 0 or negative values expecting them to mean 'unlimited'.","solutions":["Pass a positive whole number, e.g. requireLimit(10, { max: 100 })","Supply a valid fallback option, e.g. requireLimit(input, { fallback: 25 }) so missing input resolves to a default","Trim/parse CLI strings first (Number(value)) and reject NaN before calling","If you intended a hard cap, also pass max so oversized values are caught separately"],"exampleFix":"// before\nconst limit = requireLimit(opts.limit);\n// after\nconst limit = requireLimit(opts.limit ?? 25, { max: 100, name: 'limit' });","handlingStrategy":"validation","validationCode":"function isValidLimit(v) {\n  const n = Number(v);\n  return Number.isSafeInteger(n) && n > 0;\n}\nif (!isValidLimit(input)) input = 25; // default before calling requireLimit","typeGuard":"const isPositiveInt = (v) => typeof v === 'number' && Number.isSafeInteger(v) && v > 0;","tryCatchPattern":"let limit;\ntry {\n  limit = requireLimit(input, { fallback: 25, max: 100 });\n} catch (err) {\n  if (err instanceof ArgumentError) {\n    console.error(`${err.message} — ${err.hint}`);\n    limit = 25;\n  } else throw err;\n}","preventionTips":["Always pass an explicit fallback for optional limits","Parse and trim CLI strings with Number() before calling","Never use 0 or negative values to mean 'unlimited' — use a large number plus max","Coerce numeric flags at the CLI boundary once, not at each call site"],"tags":["validation","argument-error","cli-input","positive-integer"],"backgroundTag":"invalid-numeric-argument","analyzedSha":"49907e53dc3ade5c223ff0c4c2c2785687cec4e6","analyzedAt":"2026-08-29T08:14:47.543Z","schemaVersion":2},"datasetVersion":"2026-08-29T12:17:43.993Z"}