{"record":{"id":"933dd7dae11c6b1b","repo":"jax-ml/jax","slug":"expected-output-to-be-either-real-or-complex","errorCode":null,"errorMessage":"Expected 'output' to be either 'real' or 'complex', got {output=}.","messagePattern":"Expected 'output' to be either 'real' or 'complex', got (.+?)\\.","errorType":"validation","errorClass":"ValueError","httpStatus":null,"severity":"error","filePath":"jax/_src/scipy/linalg.py","lineNumber":575,"sourceCode":"    upper-triangular in this case because the input matrix is symmetric:\n\n    >>> T  # doctest: +SKIP\n    Array([[-2.0000005 ,  0.5066295 , -0.43360388],\n           [ 0.        ,  1.5505103 ,  0.74519426],\n           [ 0.        ,  0.        ,  6.449491  ]], dtype=float32)\n\n    The transformation matrix ``Z`` is unitary:\n\n    >>> jnp.allclose(Z.T @ Z, jnp.eye(3), atol=1E-5)\n    Array(True, dtype=bool)\n\n    The input can be reconstructed from the outputs:\n\n    >>> jnp.allclose(Z @ T @ Z.T, a)\n    Array(True, dtype=bool)\n  \"\"\"\n  if output not in ('real', 'complex'):\n    raise ValueError(\n      f\"Expected 'output' to be either 'real' or 'complex', got {output=}.\")\n  return _schur(ensure_arraylike(\"scipy.schur\", a), output)\n\n\ndef inv(a: ArrayLike, overwrite_a: bool = False, check_finite: bool = True) -> Array:\n  \"\"\"Return the inverse of a square matrix\n\n  JAX implementation of :func:`scipy.linalg.inv`.\n\n  Args:\n    a: array of shape ``(..., N, N)`` specifying square array(s) to be inverted.\n    overwrite_a: unused in JAX\n    check_finite: unused in JAX\n\n  Returns:\n    Array of shape ``(..., N, N)`` containing the inverse of the input.\n\n  Notes:","sourceCodeStart":557,"sourceCodeEnd":593,"githubUrl":"https://github.com/jax-ml/jax/blob/1e1c6a8fc06dfcd1247076ec5cae4640cea5d7bb/jax/_src/scipy/linalg.py#L557-L593","documentation":"jax.scipy.linalg.schur requires the `output` argument to be exactly the string 'real' or 'complex'; anything else (including typos, wrong case, or None) raises ValueError before dispatching to the underlying Schur decomposition.","triggerScenarios":"Calling jax.scipy.linalg.schur(A, output='r'), output='REAL', output=None, or any other string.","commonSituations":"Passing a variable that was never validated, or assuming schur defaults output to None like older SciPy versions; porting code where output was optional.","solutions":["Pass output='real' for real Schur form or output='complex' for complex Schur form explicitly","If building output dynamically, validate/normalize the value before calling schur"],"exampleFix":"// before\nT, Z = jax.scipy.linalg.schur(A, output=np.iscomplexobj(A))\n// after\nT, Z = jax.scipy.linalg.schur(A, output='complex' if np.iscomplexobj(A) else 'real')","handlingStrategy":"type-guard","validationCode":"null","typeGuard":"def is_valid_schur_output(o: str) -> bool: return o in ('real', 'complex')","tryCatchPattern":"try: T, Z = jax.scipy.linalg.schur(A, output=out) except ValueError as e: if 'output' in str(e): out = 'complex' if np.iscomplexobj(A) else 'real'; T, Z = jax.scipy.linalg.schur(A, output=out) else: raise","preventionTips":["Derive output from array complexity: 'complex' if np.iscomplexobj(A) else 'real'","Validate enum-like kwargs at your API boundary"],"tags":["jax","linalg","schur","argument-validation"],"backgroundTag":"invalid-argument-value","analyzedSha":"1e1c6a8fc06dfcd1247076ec5cae4640cea5d7bb","analyzedAt":"2026-08-27T09:53:25.647Z","schemaVersion":2},"datasetVersion":"2026-08-27T13:17:12.746Z"}