{"record":{"id":"d4effdb84cfaf1b8","repo":"jax-ml/jax","slug":"array-shapes-are-not-compatible-for-c-q-operatio","errorCode":null,"errorMessage":"Array shapes are not compatible for c @ Q operation: a has shape {tuple(a.shape)} so Q has {m} rows, but c has {c.shape[-1]} columns (expected {m}).","messagePattern":"Array shapes are not compatible for c @ Q operation: a has shape (.+?) so Q has (.+?) rows, but c has (.+?) columns \\(expected (.+?)\\)\\.","errorType":"validation","errorClass":"ValueError","httpStatus":null,"severity":"error","filePath":"jax/_src/scipy/linalg.py","lineNumber":1135,"sourceCode":"  if mode not in ('right', 'left'):\n    raise ValueError(f\"mode must be 'right' or 'left', got {mode!r}\")\n\n  onedim = c.ndim == 1\n  if onedim:\n    c = c[:, None] if mode == 'left' else c[None, :]\n\n  m, n = a.shape[-2:]\n  k = min(m, n)\n\n  if mode == 'left':\n    if c.shape[-2] != k:\n      raise ValueError(\n          f\"Array shapes are not compatible for Q @ c operation: \"\n          f\"a has shape {tuple(a.shape)} so Q has {k} columns, \"\n          f\"but c has {c.shape[-2]} rows (expected {k}).\")\n  else:\n    if c.shape[-1] != m:\n      raise ValueError(\n          f\"Array shapes are not compatible for c @ Q operation: \"\n          f\"a has shape {tuple(a.shape)} so Q has {m} rows, \"\n          f\"but c has {c.shape[-1]} columns (expected {m}).\")\n\n  batch = jnp.broadcast_shapes(a.shape[:-2], c.shape[:-2])\n  a = jnp.broadcast_to(a, batch + a.shape[-2:])\n  c = jnp.broadcast_to(c, batch + c.shape[-2:])\n\n  p: Array | None = None\n  if pivoting:\n    jpvt = jnp.zeros(a.shape[:-2] + (n,), dtype=jnp.int32)\n    r, p, taus = lax_linalg.geqp3(a, jpvt)\n    p -= 1  # Convert geqp3's 1-based indices to 0-based indices by subtracting 1.\n  else:\n    r, taus = lax_linalg.geqrf(a)\n\n  if m > n and mode == 'left':\n    zeros = jnp.zeros(c.shape[:-2] + (m - k,) + c.shape[-1:], dtype=c.dtype)","sourceCodeStart":1117,"sourceCodeEnd":1153,"githubUrl":"https://github.com/jax-ml/jax/blob/1e1c6a8fc06dfcd1247076ec5cae4640cea5d7bb/jax/_src/scipy/linalg.py#L1117-L1153","documentation":"In qr_multiply with mode='right', Q is m×m for a of shape (..., m, n), so c @ Q requires c.shape[-1] == m. If c's last dimension differs from m, a shape-mismatch ValueError is raised.","triggerScenarios":"Calling jax.scipy.linalg.qr_multiply(a, c, mode='right') where c's trailing dimension != a.shape[-2] (m) — e.g. c has n columns when m != n.","commonSituations":"Assuming Q is the thin/economic factor (n columns) instead of the full square one; porting code written for tall matrices to wide matrices (or vice versa).","solutions":["Pad or slice c so its last dimension equals m","If you actually want Q_k (k columns) multiplication, use mode='left' with appropriately transposed/shaped c","Double-check m = a.shape[-2] vs n = a.shape[-1] for wide inputs"],"exampleFix":"// before\na = jnp.ones((3, 5)); c = jnp.ones((2, 5))  # m=3, c.shape[-1]=5\nq, r2 = jax.scipy.linalg.qr_multiply(a, c, mode='right')\n// after\na = jnp.ones((3, 5)); c = jnp.ones((2, 3))  # last dim must equal m=3\nq, r2 = jax.scipy.linalg.qr_multiply(a, c, mode='right')","handlingStrategy":"validation","validationCode":"m = a.shape[-2]; assert mode != 'right' or c.shape[-1] == m, f'c.shape[-1] must be {m}'","typeGuard":"null","tryCatchPattern":null,"preventionTips":["Remember Q is the full m x m factor in qr_multiply","Add shape asserts in tests to catch wide-vs-tall mixups early"],"tags":["jax","linalg","shape-mismatch","qr-decomposition"],"backgroundTag":"matrix-dimension-mismatch","analyzedSha":"1e1c6a8fc06dfcd1247076ec5cae4640cea5d7bb","analyzedAt":"2026-08-27T09:53:25.647Z","schemaVersion":2},"datasetVersion":"2026-08-27T13:17:12.746Z"}