{"record":{"id":"fc65ee0da618653a","repo":"jax-ml/jax","slug":"expected-base-key-to-be-a-typed-prng-key-got-sel","errorCode":null,"errorMessage":"Expected base_key to be a typed PRNG key; got {self._base_key}","messagePattern":"Expected base_key to be a typed PRNG key; got (.+?)","errorType":"exception","errorClass":"ValueError","httpStatus":null,"severity":"error","filePath":"jax/_src/random/stateful_rng.py","lineNumber":75,"sourceCode":"    _counter: a scalar integer wrapped in a :class:`jax.Ref`.\n\n  Examples:\n\n  >>> from jax.experimental import random\n  >>> rng = random.stateful_rng(42)\n  >>> rng\n  StatefulPRNG(_base_key=Array((), dtype=key<fry>) overlaying:\n  [ 0 42], _counter=Ref(0, dtype=int32, weak_type=True))\n  \"\"\"\n  _base_key: Array\n  _counter: core.Ref\n\n  def __post_init__(self):\n    if self._base_key is api_util.SENTINEL:\n      return\n    if not (isinstance(self._base_key, Array)\n            and dtypes.issubdtype(self._base_key.dtype, dtypes.prng_key)):\n      raise ValueError(f\"Expected base_key to be a typed PRNG key; got {self._base_key}\")\n\n    # TODO(jakevdp): how to validate a traced mutable array?\n    if not (isinstance(self._counter, core.Ref) or\n            (isinstance(self._counter, core.Tracer)\n             and isinstance(self._counter.aval, state_types.AbstractRef))):\n      raise ValueError(f\"Expected counter to be a scalar integer ref; got {self._counter}\")\n\n  def key(self, shape: int | Sequence[int] = ()) -> Array:\n    \"\"\"Generate a new JAX PRNGKey, updating the internal state.\n\n    Args:\n      shape: an optional shape if returning multiple keys.\n\n    Returns:\n      A new, independent PRNG key with the same impl/dtype as\n      ``self._base_key``.\n\n    Examples:","sourceCodeStart":57,"sourceCodeEnd":93,"githubUrl":"https://github.com/jax-ml/jax/blob/1e1c6a8fc06dfcd1247076ec5cae4640cea5d7bb/jax/_src/random/stateful_rng.py#L57-L93","documentation":"jax.experimental.random.stateful_rng() optionally accepts a base_key (a typed JAX PRNG key, dtype key<fry>). In __post_init__ it validates that base_key is a JAX Array whose dtype is a prng_key subtype; passing a legacy uint32 PRNGKey, a seed integer, or any other array raises this ValueError.","triggerScenarios":"Calling stateful_rng(base_key=jax.random.PRNGKey(0)) (legacy uint32 key); passing a Python int seed as base_key instead of the seed= parameter; passing a raw uint32 array produced by key_data.","commonSituations":"Migrating old code that held jax.random.PRNGKey objects to the stateful API; parameter mix-ups between seed= and base_key=; loading unwrapped key bits from a checkpoint.","solutions":["Convert to a typed key first: stateful_rng(base_key=jax.random.key(0))","If you only have a seed, pass stateful_rng(seed=0) instead","If you have raw data, wrap it: jax.random.random_wrap(data, impl='threefry2x32')"],"exampleFix":"// before\nrng = stateful_rng(base_key=jax.random.PRNGKey(0))\n\n// after\nrng = stateful_rng(base_key=jax.random.key(0))","handlingStrategy":"type-guard","validationCode":"import jax, jax.numpy as jnp\nif not (jax.dtypes.issubdtype(base_key.dtype, jax.dtypes.prng_key)):\n    base_key = jax.random.key(0)  # or convert appropriately","typeGuard":"import jax\ndef is_typed_key(x) -> bool:\n    return isinstance(x, jax.Array) and jax.dtypes.issubdtype(x.dtype, jax.dtypes.prng_key)","tryCatchPattern":null,"preventionTips":["Pass typed keys from jax.random.key() as base_key","Use seed= for seed-based construction; convert legacy keys with jax.random.key(seed)"],"tags":["jax","prng","stateful-rng","typed-key"],"backgroundTag":"jax-prng-key-validation","analyzedSha":"1e1c6a8fc06dfcd1247076ec5cae4640cea5d7bb","analyzedAt":"2026-08-27T09:53:25.647Z","schemaVersion":2},"datasetVersion":"2026-08-27T13:17:12.746Z"}