{"record":{"id":"72f9a2f1a262a877","repo":"jackwener/OpenCLI","slug":"timeout-must-be-an-integer-30-seconds","errorCode":null,"errorMessage":"--timeout must be an integer >= 30 seconds","messagePattern":"--timeout must be an integer >= 30 seconds","errorType":"validation","errorClass":"ArgumentError","httpStatus":null,"severity":"error","filePath":"clis/wechat-channels/publish.js","lineNumber":85,"sourceCode":"  try {\n    stat = fs.statSync(resolved);\n  } catch {\n    throw new ArgumentError(`${label}文件不存在: ${resolved}`);\n  }\n  if (!stat.isFile()) {\n    throw new ArgumentError(`${label}路径不是文件: ${resolved}`);\n  }\n  const ext = path.extname(resolved).toLowerCase();\n  if (!allowedExts.has(ext)) {\n    throw new ArgumentError(`不支持的${label}格式: ${ext}（支持 ${Array.from(allowedExts).join('/')}）`);\n  }\n  return resolved;\n}\n\nfunction parseTimeoutSeconds(raw) {\n  const timeout = raw == null || raw === '' ? 600 : Number(raw);\n  if (!Number.isInteger(timeout) || timeout < 30) {\n    throw new ArgumentError('--timeout must be an integer >= 30 seconds');\n  }\n  return timeout;\n}\n\nfunction parseScheduleDate(raw) {\n  if (!raw) return null;\n  const dt = typeof raw === 'number'\n    ? new Date(raw < 1e12 ? raw * 1000 : raw)\n    : new Date(String(raw));\n  if (Number.isNaN(dt.getTime())) {\n    throw new ArgumentError(`无法解析定时时间: ${raw}`);\n  }\n  if (dt.getTime() <= Date.now()) {\n    throw new ArgumentError('定时时间必须晚于当前时间');\n  }\n  return dt;\n}\n","sourceCodeStart":67,"sourceCodeEnd":103,"githubUrl":"https://github.com/jackwener/OpenCLI/blob/49907e53dc3ade5c223ff0c4c2c2785687cec4e6/clis/wechat-channels/publish.js#L67-L103","documentation":"parseTimeoutSeconds converts the --timeout value to a number and throws ArgumentError unless it is an integer >= 30. The value drives the overall publish deadline, so non-numeric, fractional, or too-small values are rejected up front.","triggerScenarios":"Passing --timeout abc, --timeout 25, --timeout 90.5, or an empty-but-nondefault value that Number() coerces to NaN.","commonSituations":"Typos like '10m' or '1h' (not parsed), copying a timeout with a unit suffix, setting a very short timeout to 'test quickly'.","solutions":["Pass a plain integer number of seconds >= 30, e.g. --timeout 600.","Convert minutes to seconds yourself: 10m -> 600.","Omit --timeout entirely to use the default of 600 seconds."],"exampleFix":"// before\nnode publish.js --video v.mp4 --timeout 10m\n// after\nnode publish.js --video v.mp4 --timeout 600","handlingStrategy":"validation","validationCode":"const t = Number(timeoutRaw);\nif (!Number.isInteger(t) || t < 30) {\n  throw new Error('--timeout must be an integer >= 30 seconds');\n}","typeGuard":"function isValidTimeout(v) {\n  return Number.isInteger(v) && v >= 30;\n}","tryCatchPattern":"try {\n  await publish({ timeout: timeoutRaw });\n} catch (e) {\n  if (e.message.includes('--timeout')) {\n    console.error('Use plain seconds, e.g. --timeout 600');\n  }\n  throw e;\n}","preventionTips":["Pass plain integer seconds; convert '10m' to 600 yourself.","Omit --timeout to use the 600s default.","Document timeout in wrapper scripts as seconds only."],"tags":["cli","argument-validation","timeout"],"backgroundTag":"invalid-argument-value","analyzedSha":"49907e53dc3ade5c223ff0c4c2c2785687cec4e6","analyzedAt":"2026-08-29T08:14:47.543Z","schemaVersion":2},"datasetVersion":"2026-08-29T12:17:43.993Z"}