caolan/async · error · RangeError

Concurrency must not be zero

Error message

Concurrency must not be zero

What it means

async.queue and async.cargo validate the concurrency argument at construction. null/undefined defaults to 1, but an explicit 0 would create a worker pool that never processes any task, so a RangeError is thrown. Concurrency must be a positive number.

Source

Thrown at lib/internal/queue.js:11

import onlyOnce from './onlyOnce.js'
import setImmediate from './setImmediate.js'
import DLL from './DoublyLinkedList.js'
import wrapAsync from './wrapAsync.js'

export default function queue(worker, concurrency, payload) {
    if (concurrency == null) {
        concurrency = 1;
    }
    else if(concurrency === 0) {
        throw new RangeError('Concurrency must not be zero');
    }

    var _worker = wrapAsync(worker);
    var numRunning = 0;
    var workersList = [];
    const events = {
        error: [],
        drain: [],
        saturated: [],
        unsaturated: [],
        empty: []
    }

    function on (event, handler) {
        events[event].push(handler)
    }

    function once (event, handler) {

View on GitHub (pinned to 13dfaf13f3)

Solutions

  1. Pass a positive concurrency: Math.max(1, parsed)
  2. If 'unlimited' is desired, omit the argument (defaults to 1) or implement your own drain-based batching — 0 is not a valid sentinel
  3. Normalize config: const c = parseInt(raw, 10); if (!c) c = 1
  4. Fix the parsing/computation that produced 0

Example fix

// before
const q = async.queue(worker, Number(process.env.CONCURRENCY)); // 0 when unset
// after
const raw = parseInt(process.env.CONCURRENCY, 10);
const q = async.queue(worker, raw > 0 ? raw : 1);
Defensive patterns

Strategy: validation

Validate before calling

const assertQueueConcurrency = (n) => { const v = n == null ? 1 : Number(n); if (v === 0 || Number.isNaN(v)) throw new RangeError('Concurrency must not be zero'); return v; };

Type guard

function isValidConcurrency(n) {
  return n == null || (Number.isFinite(n) && n >= 1);
}

Try / catch

try {
  const q = async.queue(worker, concurrency);
} catch (err) {
  if (err instanceof RangeError) {
    console.error('Fix concurrency config; defaulting to 1');
  } else throw err;
}

Prevention

When it happens

Trigger: new async.queue(worker, 0), async.cargo(worker, 0), or passing a variable that is exactly 0 (parsed config value, Math.floor of something < 1). Note: null/undefined is silently treated as 1, only literal 0 throws.

Common situations: Reading concurrency from env/config where 0 was used to mean 'unlimited', numeric parsing returning 0 for empty strings (Number('') === 0), CPU-count computations yielding 0.

Related errors


AI-assisted analysis of caolan/async@13dfaf13f3 (2026-08-28). Data as JSON: /api/errors/340a8997a228e059. Report an issue: GitHub.