lovell/sharp · error · Error

Expected a and b to be arrays of the same length

Error message

Expected a and b to be arrays of the same length

What it means

Thrown by linear(a, b) when, after normalization, the arrays built for a and b have different lengths. linear applies the per-channel transform out = a*in + b; a and b must align channel-by-channel. Sharp normalizes scalars to single-element arrays, so a mismatch only arises when one argument is an array and the other is either a scalar or an array of a different length.

Source

Thrown at lib/operation.mjs:838

    this.options.linearA = [];
  } else if (is.number(a)) {
    this.options.linearA = [a];
  } else if (Array.isArray(a) && a.length && a.every(is.number)) {
    this.options.linearA = a;
  } else {
    throw is.invalidParameterError('a', 'number or array of numbers', a);
  }
  if (!is.defined(b)) {
    this.options.linearB = [];
  } else if (is.number(b)) {
    this.options.linearB = [b];
  } else if (Array.isArray(b) && b.length && b.every(is.number)) {
    this.options.linearB = b;
  } else {
    throw is.invalidParameterError('b', 'number or array of numbers', b);
  }
  if (this.options.linearA.length !== this.options.linearB.length) {
    throw new Error('Expected a and b to be arrays of the same length');
  }
  return this;
}

/**
 * Recombine the image with the specified matrix.
 *
 * @since 0.21.1
 *
 * @example
 * sharp(input)
 *   .recomb([
 *    [0.3588, 0.7044, 0.1368],
 *    [0.2990, 0.5870, 0.1140],
 *    [0.2392, 0.4696, 0.0912],
 *   ])
 *   .raw()
 *   .toBuffer(function(err, data, info) {

View on GitHub (pinned to 56676c6918)

Solutions

  1. Make a and b the same length: pass arrays of equal size, or pass scalars for both.
  2. To apply one multiplier and one bias to all channels, pass two scalars: linear(1.2, 0).
  3. To apply per-channel transforms, expand both to the channel count: linear([a1,a2,a3], [b1,b2,b3]).

Example fix

// before
sharp(img).linear([1.2, 1.0, 0.8], 0)

// after
sharp(img).linear([1.2, 1.0, 0.8], [0, 0, 0])
Defensive patterns

Strategy: validation

Validate before calling

function safeLinear(a, b) {
  const toArr = v => (typeof v === 'number') ? [v] : v;
  const aa = toArr(a), bb = toArr(b);
  if (Array.isArray(aa) && Array.isArray(bb) && aa.length !== bb.length) {
    throw new Error(`linear: a and b length mismatch (${aa.length} vs ${bb.length})`);
  }
  return sharp.pipeline ? null : null; // placeholder; use sharp(img).linear(a, b) directly
}
// usage: ensure a and b are both scalars, or arrays of equal length

Type guard

function linearArgsCompatible(a, b) {
  const aArr = Array.isArray(a), bArr = Array.isArray(b);
  if (aArr && bArr) return a.length === b.length;
  return true; // scalar(s) are normalized internally; mismatch only when both are arrays of differing length, or one array vs one scalar where the array has length != 1
}

Prevention

When it happens

Trigger: linear([1, 1, 1], [0]) — a has 3 entries, b has 1. linear([1.2], [0, 0, 0]) — lengths 1 vs 3. linear([1, 1, 1], 0) is fine (0 becomes [0], length 1 vs 3 -> mismatch, throws). Note: passing a scalar for one side and a multi-element array for the other triggers this because the scalar becomes a length-1 array.

Common situations: Applying a per-channel multiplier (3-element array for RGB) but a single scalar bias, forgetting to expand the scalar to a matching array. Mixing array and scalar forms unintentionally. Changing the number of channels mid-pipeline without updating the linear arrays.

Related errors


AI-assisted analysis of lovell/sharp@56676c6918 (2026-08-13). Data as JSON: /api/errors/720dfc7b93b073cb. Report an issue: GitHub.