{"record":{"id":"ee77b6242dfc797e","repo":"jackwener/OpenCLI","slug":"douyin-videos-limit-must-be-an-integer-between-m","errorCode":null,"errorMessage":"douyin videos limit must be an integer between ${MIN_LIMIT} and ${MAX_LIMIT}","messagePattern":"douyin videos limit must be an integer between (.+?) and (.+?)","errorType":"validation","errorClass":"ArgumentError","httpStatus":null,"severity":"error","filePath":"clis/douyin/videos.js","lineNumber":20,"sourceCode":"import { ArgumentError } from '@jackwener/opencli/errors';\nimport { browserFetch } from './_shared/browser-fetch.js';\nconst WORK_LIST_URL = 'https://creator.douyin.com/janus/douyin/creator/pc/work_list';\n// The server caps how many works come back per request regardless of page_size,\n// so collecting a large --limit takes several cursor hops.\nconst MAX_HOPS = 50;\nconst DEFAULT_LIMIT = 20;\nconst MIN_LIMIT = 1;\nconst MAX_LIMIT = MAX_HOPS * 50;\nfunction isScheduledWork(work) {\n    return (work.public_time ?? 0) > Date.now() / 1000;\n}\nfunction countEligibleWorks(items, status) {\n    return status === 'scheduled' ? items.filter(isScheduledWork).length : items.length;\n}\nexport function normalizeVideosLimit(raw) {\n    const value = raw === undefined || raw === null || raw === '' ? DEFAULT_LIMIT : Number(raw);\n    if (!Number.isInteger(value) || value < MIN_LIMIT || value > MAX_LIMIT) {\n        throw new ArgumentError(`douyin videos limit must be an integer between ${MIN_LIMIT} and ${MAX_LIMIT}`);\n    }\n    return value;\n}\nfunction pageSizeForLimit(limit) {\n    if (limit < 20)\n        return 20;\n    if (limit > 50)\n        return 50;\n    return limit;\n}\nfunction normalizeVideoStatus(status, publicTime) {\n    if (typeof status === 'number')\n        return status;\n    if (!status)\n        return publicTime && publicTime > Date.now() / 1000 ? 'scheduled' : 'published';\n    if (status.is_delete)\n        return 'deleted';\n    if (status.is_prohibited)","sourceCodeStart":2,"sourceCodeEnd":38,"githubUrl":"https://github.com/jackwener/OpenCLI/blob/49907e53dc3ade5c223ff0c4c2c2785687cec4e6/clis/douyin/videos.js#L2-L38","documentation":"An ArgumentError thrown by normalizeVideosLimit when the --limit value for douyin videos is not an integer, or falls outside [MIN_LIMIT, MAX_LIMIT]. Note the special case: undefined/null/'' defaults to DEFAULT_LIMIT, but any other non-numeric or non-integer string (e.g. '10.5', 'abc') becomes NaN or a float and fails the integer check.","triggerScenarios":"Calling `douyin videos --limit 0`, a negative number, a decimal like 2.5, a non-numeric string, or a value above the maximum, where Number.isInteger(value) is false or the bounds check fails.","commonSituations":"Shell/config supplying 'all' or a comma-separated list instead of a number; locale-formatted numbers ('1,000'); float math upstream producing 19.999999; unit confusion (expecting pages instead of items).","solutions":["Pass an integer within the allowed range, e.g. `--limit 50`.","Omit --limit entirely to use the default value.","Coerce upstream: Math.round / parseInt before passing, and clamp into [MIN_LIMIT, MAX_LIMIT].","Log the exact flag value if your wrapper builds args dynamically — an empty-ish or malformed value bypasses the default and fails validation."],"exampleFix":"// before\nawait run(['douyin', 'videos', '--limit', String(opts.count ?? '')]);\n// after\nconst limit = Math.max(1, Math.round(Number(opts.count) || 50));\nawait run(['douyin', 'videos', '--limit', String(limit)]);","handlingStrategy":"validation","validationCode":"function coerceVideosLimit(v, { min, max, dflt }) {\n  if (v === undefined || v === null || v === '') return dflt;\n  const n = Number(v);\n  if (!Number.isInteger(n) || n < min || n > max) throw new Error(`limit must be an integer in [${min}, ${max}]`);\n  return n;\n}","typeGuard":"function isValidLimit(v, min, max) {\n  const n = Number(v);\n  return Number.isInteger(n) && n >= min && n <= max;\n}","tryCatchPattern":"try {\n  await run('douyin videos', { limit });\n} catch (e) {\n  if (e.name === 'ArgumentError' && /limit must be an integer/.test(e.message)) {\n    console.error('Pass an integer limit or omit --limit for the default');\n    process.exitCode = 2;\n    return;\n  }\n  throw e;\n}","preventionTips":["Sanitize numeric flags with Number() + Number.isInteger before passing them on.","Never pass formatted strings like '1,000' or 'all' as --limit.","Omit the flag to get DEFAULT_LIMIT instead of passing ''."],"tags":["argument-error","douyin","range-validation","input-validation"],"backgroundTag":"invalid-parameter-value","analyzedSha":"49907e53dc3ade5c223ff0c4c2c2785687cec4e6","analyzedAt":"2026-08-29T08:14:47.543Z","schemaVersion":2},"datasetVersion":"2026-08-29T17:17:51.833Z"}