trekhleb/javascript-algorithms · error · Error

Matrices have incompatible shape for multiplication

Error message

Matrices have incompatible shape for multiplication

What it means

Thrown by dot(a, b) in src/algorithms/math/matrix/Matrix.js:135 when the inner dimensions of two 2D matrices do not agree: the number of columns of a (aShape[1]) must equal the number of rows of b (bShape[0]). This is the classic (n x m) * (m x p) rule of matrix multiplication; a 2x3 times a 2x2 fails because 3 !== 2. Both inputs have already passed validate2D() at this point, so the error is purely about inner-dimension alignment, not type or rank.

Source

Thrown at src/algorithms/math/matrix/Matrix.js:135

  return generate(mShape, () => 0);
};

/**
 * @param {Matrix} a
 * @param {Matrix} b
 * @return Matrix
 * @throws {Error}
 */
export const dot = (a, b) => {
  // Validate inputs.
  validate2D(a);
  validate2D(b);

  // Check dimensions.
  const aShape = shape(a);
  const bShape = shape(b);
  if (aShape[1] !== bShape[0]) {
    throw new Error('Matrices have incompatible shape for multiplication');
  }

  // Perform matrix multiplication.
  const outputShape = [aShape[0], bShape[1]];
  const c = zeros(outputShape);

  for (let bCol = 0; bCol < b[0].length; bCol += 1) {
    for (let aRow = 0; aRow < a.length; aRow += 1) {
      let cellSum = 0;
      for (let aCol = 0; aCol < a[aRow].length; aCol += 1) {
        cellSum += a[aRow][aCol] * b[aCol][bCol];
      }
      c[aRow][bCol] = cellSum;
    }
  }

  return c;
};

View on GitHub (pinned to 85293e3e2b)

Solutions

  1. Log shape(a) and shape(b) and confirm which orientation you intended
  2. Transpose the right operand: dot(a, t(b)) using the exported t() when b is oriented wrong
  3. Swap operand order: dot(b, a) is often legal where dot(a, b) is not
  4. If a weights matrix expects a different feature count, fix the feature vector upstream to match

Example fix

// before
import { dot } from './src/algorithms/math/matrix/Matrix';
const result = dot([[1, 2, 3], [4, 5, 6]], [[1, 2], [3, 4]]);
// throws: 2x3 * 2x2, inner dims 3 !== 2

// after
const result = dot([[1, 2], [3, 4], [5, 6]], [[1, 2], [3, 4]]);
// ok: 3x2 * 2x2
Defensive patterns

Strategy: validation

Validate before calling

import { shape, dot } from './src/algorithms/math/matrix/Matrix';

const canMultiply = (a, b) => shape(a)[1] === shape(b)[0];
if (!canMultiply(a, b)) {
  throw new TypeError('cannot multiply ' + JSON.stringify(shape(a)) + ' by ' + JSON.stringify(shape(b)));
}
const product = dot(a, b);

Type guard

import { shape } from './src/algorithms/math/matrix/Matrix';

const isMultipliablePair = (a, b) => {
  const sa = shape(a);
  const sb = shape(b);
  return sa.length === 2 && sb.length === 2 && sa[1] === sb[0];
};

Try / catch

import { dot, t } from './src/algorithms/math/matrix/Matrix';

try {
  c = dot(a, b);
} catch (e) {
  if (e.message === 'Matrices have incompatible shape for multiplication') {
    c = dot(a, t(b)); // orientation was wrong; retry transposed
  } else {
    throw e;
  }
}

Prevention

When it happens

Trigger: dot([[1,2,3],[4,5,6]], [[1,2],[3,4]]) (2x3 * 2x2); multiplying a weights matrix by a feature vector shaped as a row when it must be a column; chaining dot(a, b) where b came from a previous dot with a different output width.

Common situations: Row-vector vs column-vector orientation confusion, weight matrices from a trained model expecting a different feature count than the input provides, swapped operand order (dot(a, b) vs dot(b, a)), or an upstream schema change that added a feature column.

Related errors


AI-assisted analysis of trekhleb/javascript-algorithms@85293e3e2b (2026-08-24). Data as JSON: /api/errors/30c765d25d72cbb6. Report an issue: GitHub.