jax-ml/jax · error · ValueError

Unexpected precision specifier value {precision}

Error message

Unexpected precision specifier value {precision}

What it means

The LSTM precision parser accepts only specific lax.Precision values (HIGHEST, HIGH, DEFAULT) in tuple or scalar form. Anything else — an invalid enum, a string like 'high', or a malformed tuple — raises ValueError.

Source

Thrown at jax/experimental/rnn.py:267

  #   if precision is None and config.jax_default_matmul_precision is not None:
  #     precision = Precision(config.jax_default_matmul_precision)
  #   else:
  #     precision = None
  #
  # but we prefer to still invoke it here for consistency
  precision = lax.canonicalize_precision(precision)
  if precision is None or not (isinstance(precision, tuple) and len(precision) == 2):
    return True
  # cuDNN allows only one precision specifier per RNN op
  match precision:
    case (lax.Precision.HIGHEST, _):
      return False
    case (lax.Precision.HIGH, _):
      return True
    case (lax.Precision.DEFAULT, _): # bfloat16
      raise NotImplementedError("bfloat16 support not implemented for LSTM")
    case _:
      raise ValueError(f"Unexpected precision specifier value {precision}")


@partial(custom_vjp, nondiff_argnums=(5, 6, 7, 8, 9, 10))
def lstm(x: Array, h_0: Array, c_0: Array, weights: Array, seq_lengths: Array,
         input_size: int, hidden_size: int, num_layers: int, dropout: float,
         bidirectional: bool, precision: lax.PrecisionLike = None) -> tuple[Array, Array, Array]:
  """LSTM via CuDNN or HIPDNN (not-yet-supported).

  Assume batch-first inputs.

  Arguments:
    x: (batch_size, max_seq_length, input_size)
    h_0: (num_directions * num_layers, batch_size, hidden_size)
    c_0: (num_directions * num_layers, batch_size, hidden_size)
    weights: (num_params,) where num_params = get_num_params_in_lstm(...)
    seq_lengths: (batch_size,)
  Returns: (y, h_n, c_n, reserve_space).
    y: (batch_size, max_seq_length, hidden_size * num_directions)

View on GitHub (pinned to 1e1c6a8fc0)

Solutions

  1. Pass a valid lax.Precision enum or tuple of enums, e.g. lax.Precision.HIGHEST or (lax.Precision.HIGHEST, lax.Precision.HIGHEST)
  2. Use None only if the version supports it; otherwise pick an explicit enum
  3. Check the installed JAX version's accepted values in rnn.py

Example fix

# before
lstm(..., precision='high')
# after
lstm(..., precision=lax.Precision.HIGH)
Defensive patterns

Strategy: type-guard

Validate before calling

assert precision is None or precision in (lax.Precision.HIGHEST, lax.Precision.HIGH, lax.Precision.DEFAULT) or all(p in lax.Precision for p in precision)

Type guard

def valid_precision(p) -> bool:
    ok = {lax.Precision.HIGHEST, lax.Precision.HIGH, lax.Precision.DEFAULT}
    if isinstance(p, tuple):
        return all(x in ok for x in p)
    return p is None or p in ok

Prevention

When it happens

Trigger: Calling jax.experimental.rnn.lstm with precision set to a raw string ('high'), a lax.Precision combined with lax.Precision via unsupported ops, or a nested/incorrect tuple structure.

Common situations: Copy-pasting precision strings from JAX docs for matmul-like APIs; passing precision=(lax.Precision.DEFAULT, None) or enum combos the matcher doesn't handle.

Understand the failure class

Background: Invalid enum value errors: "Unknown type", "Invalid scope", "must be one of" — when a string is not on the library's allowed list — this error's family across 23 libraries.

Related errors


AI-assisted analysis of jax-ml/jax@1e1c6a8fc0 (2026-08-27). Data as JSON: /api/errors/24497941684bb8cb. Report an issue: GitHub.