{"record":{"id":"f304ca7d81706e79","repo":"trekhleb/javascript-algorithms","slug":"matrices-have-different-shapes","errorCode":null,"errorMessage":"Matrices have different shapes","messagePattern":"Matrices have different shapes","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"src/algorithms/math/matrix/Matrix.js","lineNumber":74,"sourceCode":" *\n * @param {Matrix} a\n * @param {Matrix} b\n * @trows {Error}\n */\nexport const validateSameShape = (a, b) => {\n  validateType(a);\n  validateType(b);\n\n  const aShape = shape(a);\n  const bShape = shape(b);\n\n  if (aShape.length !== bShape.length) {\n    throw new Error('Matrices have different dimensions');\n  }\n\n  while (aShape.length && bShape.length) {\n    if (aShape.pop() !== bShape.pop()) {\n      throw new Error('Matrices have different shapes');\n    }\n  }\n};\n\n/**\n * Generates the matrix of specific shape with specific values.\n *\n * @param {Shape} mShape - the shape of the matrix to generate\n * @param {function({CellIndex}): Cell} fill - cell values of a generated matrix.\n * @returns {Matrix}\n */\nexport const generate = (mShape, fill) => {\n  /**\n   * Generates the matrix recursively.\n   *\n   * @param {Shape} recShape - the shape of the matrix to generate\n   * @param {CellIndices} recIndices\n   * @returns {Matrix}","sourceCodeStart":56,"sourceCodeEnd":92,"githubUrl":"https://github.com/trekhleb/javascript-algorithms/blob/85293e3e2b88f4d2ce330d956b139cf628aa1e82/src/algorithms/math/matrix/Matrix.js#L56-L92","documentation":"Thrown by validateSameShape() in src/algorithms/math/matrix/Matrix.js:74 when two matrices passed to add(), mul() or sub() have the same number of dimensions but differ in size along at least one axis. The validator pops sizes off both shape arrays and compares them axis by axis, so [[1,2],[3,4]] (shape [2,2]) plus [[1,2,3],[4,5,6]] (shape [2,3]) fails on the second axis. Element-wise operations are only defined for identically shaped inputs, so the library fails fast instead of producing undefined cells.","triggerScenarios":"add/mul/sub where row counts differ (2x2 + 2x3), column counts differ, or in higher-rank inputs one batch has more entries than the other along any axis.","commonSituations":"Ragged rows from CSV/JSON parsing, concatenating matrices then forgetting to trim to equal extent, off-by-one slicing (data.slice(0, n) vs data.slice(0, n - 1)), or a pipeline change that altered one matrix dimension while the other stayed fixed.","solutions":["Print shape(a) and shape(b) with the exported shape() helper to identify the offending axis","Slice the larger matrix (b.map(row => row.slice(0, a[0].length)) or b.slice(0, a.length)) so both shapes match exactly","Pad the smaller one by building zeros(shape(a)) and copying values in","Fix the mis-sized input at its source rather than patching at the call site"],"exampleFix":"// before\nimport { add } from './src/algorithms/math/matrix/Matrix';\nconst sum = add([[1, 2], [3, 4]], [[1, 2, 3], [4, 5, 6]]);\n// throws: shapes [2,2] vs [2,3]\n\n// after\nconst trimmed = [[1, 2, 3], [4, 5, 6]].map((row) => row.slice(0, 2));\nconst sum = add([[1, 2], [3, 4]], trimmed);\n// both shapes are [2,2]","handlingStrategy":"validation","validationCode":"import { shape } from './src/algorithms/math/matrix/Matrix';\n\nconst sameShape = (a, b) => {\n  const sa = shape(a);\n  const sb = shape(b);\n  return sa.length === sb.length && sa.every((dim, i) => dim === sb[i]);\n};\nif (!sameShape(a, b)) {\n  throw new TypeError('shape mismatch: ' + JSON.stringify(shape(a)) + ' vs ' + JSON.stringify(shape(b)));\n}\nconst sum = add(a, b);","typeGuard":"import { shape } from './src/algorithms/math/matrix/Matrix';\n\nconst isSameShapeMatrix = (a, b) => {\n  const sa = shape(a);\n  const sb = shape(b);\n  return Array.isArray(a) && Array.isArray(b) && sa.length === sb.length && sa.every((d, i) => d === sb[i]);\n};","tryCatchPattern":"try {\n  result = sub(a, b);\n} catch (e) {\n  if (e.message === 'Matrices have different shapes') {\n    result = zeros(shape(a)); // or log and skip this batch\n  } else {\n    throw e;\n  }\n}","preventionTips":["Assert identical shapes in unit tests for every element-wise operation","Validate row lengths when parsing ragged CSV/JSON before building matrices","Derive all matrices in a pipeline stage from one canonical shape constant"],"tags":["matrix","shape-validation","math","off-by-one"],"backgroundTag":"matrix-shape-mismatch","analyzedSha":"85293e3e2b88f4d2ce330d956b139cf628aa1e82","analyzedAt":"2026-08-24T05:59:10.417Z","schemaVersion":2},"datasetVersion":"2026-08-24T07:17:09.176Z"}