{"record":{"id":"a2b59dd162c75a8e","repo":"jax-ml/jax","slug":"the-first-argument-to-householder-product-must-hav","errorCode":null,"errorMessage":"The first argument to householder_product must have at least as many rows as columns, got shape {a_shape}","messagePattern":"The first argument to householder_product must have at least as many rows as columns, got shape (.+?)","errorType":"validation","errorClass":"ValueError","httpStatus":null,"severity":"error","filePath":"jax/_src/lax/linalg.py","lineNumber":1424,"sourceCode":"      \"EQ\", \"SIGNED\")\n  return [\n      _replace_not_ok_with_nan(ctx, batch_dims, ok, a, ctx.avals_out[0]),\n      _replace_not_ok_with_nan(ctx, batch_dims, ok, taus, ctx.avals_out[1]),\n  ]\n\n\nhessenberg_p = linalg_primitive(\n    _hessenberg_dtype_rule, (_float | _complex,), (2,), _hessenberg_shape_rule,\n    \"hessenberg\", multiple_results=True)\nmlir.register_lowering(hessenberg_p, _hessenberg_cpu_lowering, platform=\"cpu\")\n\n\n# Householder product\n\ndef _householder_product_shape_rule(a_shape, taus_shape, **_):\n  m, n = a_shape\n  if m < n:\n    raise ValueError(\n        \"The first argument to householder_product must have at least as many \"\n        f\"rows as columns, got shape {a_shape}\")\n  k = taus_shape[0]\n  if k > core.min_dim(m, n):\n    raise ValueError(\n        \"The second argument to householder_product must not have more rows \"\n        \"than the minimum of the first argument's rows and columns.\")\n  return a_shape\n\n\ndef _householder_product_lowering(ctx, a, taus):\n  aval_out, = ctx.avals_out\n  if not is_constant_shape(aval_out.shape):\n    result_shapes = [\n        mlir.eval_dynamic_shape_as_tensor(ctx, aval_out.shape)]\n  else:\n    result_shapes = None\n  flat_res_types, _ = mlir.ir_tree_registry.flatten(","sourceCodeStart":1406,"sourceCodeEnd":1442,"githubUrl":"https://github.com/jax-ml/jax/blob/1e1c6a8fc06dfcd1247076ec5cae4640cea5d7bb/jax/_src/lax/linalg.py#L1406-L1442","documentation":"jax/_src/lax/linalg.py:1424 in _householder_product_shape_rule. householder_product(a, taus) reconstructs Q from the Householder reflectors stored in a lower-trapezoidal a; it requires a's first dim >= second dim (m >= n). If the reflector matrix has more columns than rows the ValueError fires.","triggerScenarios":"Calling jax.lax.linalg.householder_product with a of shape (m, n) where m < n — typically a truncated/mis-sliced output of geqrf, or applying the product for a tall Q to a wide reflector block.","commonSituations":"Chaining qr factorization outputs into householder_product with wrong slicing; porting LAPACK orgqr call sequences where k reflectors and ldq layouts differ; off-by-one when extracting the reflector panel from QR output.","solutions":["Check a.shape[0] >= a.shape[1] before the call; slice the reflector block correctly (a[:, :k])","Re-derive from jnp.linalg.qr directly if you only need Q","Verify taus has k <= min(m, n) elements matching the reflector count"],"exampleFix":"// before\nq = jax.lax.linalg.householder_product(a, taus)  # a: (3, 5)\n// after\nq = jax.lax.linalg.householder_product(a[:, :a.shape[0]], taus)  # square/tall block","handlingStrategy":"validation","validationCode":"assert a.shape[0] >= a.shape[1], f'need m>=n, got {a.shape}'","typeGuard":"def valid_reflector_shape(a: jax.Array) -> bool:\n    return a.ndim >= 2 and a.shape[-2] >= a.shape[-1]","tryCatchPattern":null,"preventionTips":["Slice reflector block a[:, :k] from QR output before householder_product"],"tags":["jax","linalg","householder","shape-validation","qr"],"backgroundTag":"invalid-matrix-dimensions","analyzedSha":"1e1c6a8fc06dfcd1247076ec5cae4640cea5d7bb","analyzedAt":"2026-08-27T09:53:25.647Z","schemaVersion":2},"datasetVersion":"2026-08-27T13:17:12.746Z"}