{"record":{"id":"bcfde93e62913337","repo":"jax-ml/jax","slug":"prng-key-seed-must-be-an-integer-got-seed-r-bcfde9","errorCode":null,"errorMessage":"PRNG key seed must be an integer; got {seed!r}","messagePattern":"PRNG key seed must be an integer; got (.+?)","errorType":"exception","errorClass":"TypeError","httpStatus":null,"severity":"error","filePath":"jax/_src/random/threefry2x32.py","lineNumber":66,"sourceCode":"  \"\"\"Create a single raw threefry PRNG key from an integer seed.\n\n  Args:\n    seed: a 64- or 32-bit integer used as the value of the key.\n\n  Returns:\n    The PRNG key contents, modeled as an array of shape (2,) and dtype\n    uint32. The key is constructed from a 64-bit seed by effectively\n    bit-casting to a pair of uint32 values (or from a 32-bit seed by\n    first padding out with zeros).\n  \"\"\"\n  return _threefry_seed(seed)\n\n@api.jit(inline=True)\ndef _threefry_seed(seed: typing.Array) -> typing.Array:\n  if seed.shape:\n    raise TypeError(f\"PRNG key seed must be a scalar; got {seed!r}.\")\n  if not np.issubdtype(seed.dtype, np.integer):\n    raise TypeError(f\"PRNG key seed must be an integer; got {seed!r}\")\n  convert = lambda k: lax.expand_dims(lax.convert_element_type(k, np.uint32), [0])\n  k1 = convert(\n      lax.shift_right_logical(seed, lax._const(seed, 32)))\n  with config.numpy_dtype_promotion('standard'):\n    # TODO(jakevdp): in X64 mode, this can generate 64-bit computations for 32-bit\n    # inputs. We should avoid this.\n    k2 = convert(jnp.bitwise_and(seed, np.uint32(0xFFFFFFFF)))\n  return lax.concatenate([k1, k2], 0)\n\n\ndef _make_rotate_left(dtype):\n  if not dtypes.issubdtype(dtype, np.integer):\n    raise TypeError(\"_rotate_left only accepts integer dtypes.\")\n  nbits = np.array(dtypes.iinfo(dtype).bits, dtype)\n\n  def _rotate_left(x, d):\n    if lax.dtype(d) != dtype:\n      d = lax.convert_element_type(d, dtype)","sourceCodeStart":48,"sourceCodeEnd":84,"githubUrl":"https://github.com/jax-ml/jax/blob/1e1c6a8fc06dfcd1247076ec5cae4640cea5d7bb/jax/_src/random/threefry2x32.py#L48-L84","documentation":"PRNG seeds must be integers because threefry hashes the integer bits into two uint32 key words. _threefry_seed raises this TypeError when the seed is a float (e.g. 42.0 or np.float64), bool-kind arrays are the only tolerated exception downstream in some paths, and non-integer inputs cannot be hashed deterministically across platforms.","triggerScenarios":"jax.random.PRNGKey(42.0); PRNGKey(np.float32(0)); seeds read from JSON/config as floats; dividing a seed expression ('seed/n_devices') producing floats.","commonSituations":"JSON/YAML configs where 0 parses as int but 0.0 or computed values parse as float; hyperparameter sweeps computing seeds arithmetically; np.random seeds passed through float dtypes.","solutions":["Coerce to int: jax.random.key(int(seed))","Fix config parsing to yield ints (e.g. schema validation)","When computing seeds arithmetically, wrap the result in int()"],"exampleFix":"// before\nkey = jax.random.PRNGKey(42.0)\n\n// after\nkey = jax.random.PRNGKey(42)","handlingStrategy":"validation","validationCode":"seed = int(seed) if not hasattr(seed, 'dtype') else seed\n# or generically:\nimport numpy as np\nif not np.issubdtype(np.asarray(seed).dtype, np.integer):\n    seed = int(seed)","typeGuard":"import numpy as np\ndef is_integer_seed(s) -> bool:\n    return np.issubdtype(np.asarray(s).dtype, np.integer)","tryCatchPattern":null,"preventionTips":["Coerce seeds with int() at API boundaries","Validate config values as integers when parsing"],"tags":["jax","prng","seed","dtype","integer"],"backgroundTag":"jax-invalid-seed","analyzedSha":"1e1c6a8fc06dfcd1247076ec5cae4640cea5d7bb","analyzedAt":"2026-08-27T09:53:25.647Z","schemaVersion":2},"datasetVersion":"2026-08-27T13:17:12.746Z"}