{"record":{"id":"bba3e1104d5ddb42","repo":"neoclide/coc.nvim","slug":"name-must-be-a-positive-finite-number","errorCode":null,"errorMessage":"${name} must be a positive finite number","messagePattern":"(.+?) must be a positive finite number","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"src/model/download.ts","lineNumber":218,"sourceCode":"  res.pipe(output)\n  return emitter\n}\n\n/**\n * Download file from url, with optional untar/unzip support.\n * @param {string} url\n * @param {DownloadOptions} options contains dest folder and optional onProgress callback\n */\nexport default function download(urlInput: string | URL, options: DownloadOptions, token?: CancellationToken, obj: any = {}): Promise<string> {\n  let url = toURL(urlInput)\n  let { etagAlgorithm } = options\n  let { dest, onProgress, extract } = options\n  for (let [name, value] of Object.entries({\n    maxDownloadSize: options.maxDownloadSize,\n    maxExtractSize: options.maxExtractSize,\n    maxArchiveEntries: options.maxArchiveEntries\n  })) {\n    if (value !== undefined && (!Number.isFinite(value) || value <= 0)) throw new Error(`${name} must be a positive finite number`)\n  }\n  if (!dest || !path.isAbsolute(dest)) {\n    throw new Error(`Invalid dest path: ${dest}`)\n  }\n  // Use one canonical lexical representation for filesystem operations and\n  // archive-boundary checks. path.resolve also removes a trailing separator.\n  dest = path.resolve(dest)\n  if (!fs.existsSync(dest)) {\n    fs.mkdirSync(dest, { recursive: true })\n  } else {\n    let stat = fs.statSync(dest)\n    if (stat && !stat.isDirectory()) {\n      throw new Error(`${dest} exists, but not directory!`)\n    }\n  }\n  let mod = getRequestModule(url)\n  let opts = resolveRequestOptions(url, options)\n  if (!opts.agent && options.agent) opts.agent = options.agent","sourceCodeStart":200,"sourceCodeEnd":236,"githubUrl":"https://github.com/neoclide/coc.nvim/blob/50e974d9692461a69147d5cab146a8d3e439abe4/src/model/download.ts#L200-L236","documentation":"download() validates its optional size-limit options (maxDownloadSize, maxExtractSize, maxArchiveEntries) before starting any network or extraction work. Each must be either undefined or a positive finite number; passing 0, a negative value, NaN, or Infinity throws this error naming the offending option.","triggerScenarios":"Calling download({ url, dest, maxDownloadSize: 0 }), maxExtractSize: -1, maxArchiveEntries: NaN/Infinity, or passing non-numeric values from unparsed config (e.g. string '100' from env/config).","commonSituations":"Reading limits from configuration files or environment variables without Number parsing; using 0 intending 'unlimited' (0 is invalid, omit the option instead); arithmetic producing NaN.","solutions":["Pass a positive finite number (e.g. maxDownloadSize: 100 * 1024 * 1024) or omit the option entirely for unlimited.","If loading from config/env, coerce and validate: Number(value) and check Number.isFinite(v) && v > 0.","Replace sentinel values like 0 or -1 for 'no limit' with undefined."],"exampleFix":"// before\ndownload({ url, dest, maxDownloadSize: 0 })\n// after\ndownload({ url, dest, maxDownloadSize: 512 * 1024 * 1024 }) // or omit for unlimited","handlingStrategy":"validation","validationCode":"function validLimit(v) { return v === undefined || (Number.isFinite(v) && v > 0) }\nif (!validLimit(opts.maxDownloadSize) || !validLimit(opts.maxExtractSize) || !validLimit(opts.maxArchiveEntries))\n  throw new Error('size-limit options must be positive finite numbers or undefined')","typeGuard":"function isPositiveFinite(v: unknown): v is number { return typeof v === 'number' && Number.isFinite(v) && v > 0 }","tryCatchPattern":"try {\n  await download({ url, dest, maxDownloadSize })\n} catch (e) {\n  if (/must be a positive finite number/.test(e.message)) {\n    return download({ url, dest }) // retry with defaults (no limit)\n  }\n  throw e\n}","preventionTips":["Omit limit options entirely when you want no limit; never pass 0.","Parse config values with Number() and validate with Number.isFinite before use.","Define named constants (e.g. 512 * 1024 * 1024) instead of ad-hoc magic numbers."],"tags":["validation","configuration","download"],"backgroundTag":"invalid-option-value","analyzedSha":"50e974d9692461a69147d5cab146a8d3e439abe4","analyzedAt":"2026-08-31T11:17:23.966Z","schemaVersion":2},"datasetVersion":"2026-08-31T14:17:45.589Z"}