neoclide/coc.nvim · error

${name} must be a positive finite number

Error message

${name} must be a positive finite number

What it means

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.

Source

Thrown at src/model/download.ts:218

  res.pipe(output)
  return emitter
}

/**
 * Download file from url, with optional untar/unzip support.
 * @param {string} url
 * @param {DownloadOptions} options contains dest folder and optional onProgress callback
 */
export default function download(urlInput: string | URL, options: DownloadOptions, token?: CancellationToken, obj: any = {}): Promise<string> {
  let url = toURL(urlInput)
  let { etagAlgorithm } = options
  let { dest, onProgress, extract } = options
  for (let [name, value] of Object.entries({
    maxDownloadSize: options.maxDownloadSize,
    maxExtractSize: options.maxExtractSize,
    maxArchiveEntries: options.maxArchiveEntries
  })) {
    if (value !== undefined && (!Number.isFinite(value) || value <= 0)) throw new Error(`${name} must be a positive finite number`)
  }
  if (!dest || !path.isAbsolute(dest)) {
    throw new Error(`Invalid dest path: ${dest}`)
  }
  // Use one canonical lexical representation for filesystem operations and
  // archive-boundary checks. path.resolve also removes a trailing separator.
  dest = path.resolve(dest)
  if (!fs.existsSync(dest)) {
    fs.mkdirSync(dest, { recursive: true })
  } else {
    let stat = fs.statSync(dest)
    if (stat && !stat.isDirectory()) {
      throw new Error(`${dest} exists, but not directory!`)
    }
  }
  let mod = getRequestModule(url)
  let opts = resolveRequestOptions(url, options)
  if (!opts.agent && options.agent) opts.agent = options.agent

View on GitHub (pinned to 50e974d969)

Solutions

  1. Pass a positive finite number (e.g. maxDownloadSize: 100 * 1024 * 1024) or omit the option entirely for unlimited.
  2. If loading from config/env, coerce and validate: Number(value) and check Number.isFinite(v) && v > 0.
  3. Replace sentinel values like 0 or -1 for 'no limit' with undefined.

Example fix

// before
download({ url, dest, maxDownloadSize: 0 })
// after
download({ url, dest, maxDownloadSize: 512 * 1024 * 1024 }) // or omit for unlimited
Defensive patterns

Strategy: validation

Validate before calling

function validLimit(v) { return v === undefined || (Number.isFinite(v) && v > 0) }
if (!validLimit(opts.maxDownloadSize) || !validLimit(opts.maxExtractSize) || !validLimit(opts.maxArchiveEntries))
  throw new Error('size-limit options must be positive finite numbers or undefined')

Type guard

function isPositiveFinite(v: unknown): v is number { return typeof v === 'number' && Number.isFinite(v) && v > 0 }

Try / catch

try {
  await download({ url, dest, maxDownloadSize })
} catch (e) {
  if (/must be a positive finite number/.test(e.message)) {
    return download({ url, dest }) // retry with defaults (no limit)
  }
  throw e
}

Prevention

When it happens

Trigger: 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).

Common situations: 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.

Understand the failure class

Background: Invalid option value errors: "must be one of", "is not a valid", and "only allows" failures explained — this error's family across 23 libraries.

Related errors


AI-assisted analysis of neoclide/coc.nvim@50e974d969 (2026-08-31). Data as JSON: /api/errors/bba3e1104d5ddb42. Report an issue: GitHub.