{"record":{"id":"035c2fa7a8607d62","repo":"jax-ml/jax","slug":"n-must-be-a-non-negative-integer","errorCode":null,"errorMessage":"n must be a non-negative integer.","messagePattern":"n must be a non-negative integer\\.","errorType":"exception","errorClass":"ValueError","httpStatus":null,"severity":"error","filePath":"jax/_src/scipy/special.py","lineNumber":3138,"sourceCode":"def bernoulli(n: int) -> Array:\n  r\"\"\"Generate the Bernoulli numbers :math:`B_0` through :math:`B_n`, inclusive.\n\n  JAX implementation of :func:`scipy.special.bernoulli`.\n\n  Args:\n    n: integer, the index of the last Bernoulli number to generate.\n\n  Returns:\n    Array containing the Bernoulli numbers :math:`B_0` through :math:`B_n`, inclusive.\n\n  Notes:\n    ``bernoulli`` generates numbers using the :math:`B_n^-` convention,\n    such that :math:`B_1=-1/2`.\n  \"\"\"\n  # Generate Bernoulli numbers using the Chowla and Hartung algorithm.\n  n = core.concrete_or_error(operator.index, n, \"Argument n of bernoulli\")\n  if n < 0:\n    raise ValueError(\"n must be a non-negative integer.\")\n  b3 = jnp.array([1, -1/2, 1/6])\n  if n < 3:\n    return b3[:n + 1]\n  bn = jnp.zeros(n + 1).at[:3].set(b3)\n  m = jnp.arange(4, n + 1, 2, dtype=bn.dtype)\n  q1 = (1. / np.pi ** 2) * jnp.cumprod(-(m - 1) * m / 4 / np.pi ** 2)\n  k = jnp.arange(2, 50, dtype=bn.dtype)  # Choose 50 because 2 ** -50 < 1E-15\n  q2 = jnp.sum(k[:, None] ** -m[None, :], axis=0)\n  return bn.at[4::2].set(q1 * (1 + q2))\n\n\n@custom_derivatives.custom_jvp\ndef poch(z: ArrayLike, m: ArrayLike) -> Array:\n  r\"\"\"The Pochhammer symbol.\n\n  JAX implementation of :obj:`scipy.special.poch`.\n\n  .. math::","sourceCodeStart":3120,"sourceCodeEnd":3156,"githubUrl":"https://github.com/jax-ml/jax/blob/1e1c6a8fc06dfcd1247076ec5cae4640cea5d7bb/jax/_src/scipy/special.py#L3120-L3156","documentation":"jax.scipy.special.bernoulli requires n to be a non-negative Python integer. Because Bernoulli numbers are a finite symbolic sequence (not an elementwise computation), n must be a concrete static value; it is passed through core.concrete_or_error(operator.index, n) which both rejects traced/JIT-abstract values and non-integer types. Negative n reaches the explicit ValueError.","triggerScenarios":"Calling jax.scipy.special.bernoulli(n) with a negative integer, a float like 4.0 (operator.index rejects it), or a JAX tracer/Array inside jit/grad/vmap where n is not static.","commonSituations":"Passing a computed loop index or an array-typed value as n under @jit; passing a negative value by mistake from user input; using bernoulli inside a differentiated function.","solutions":["Pass a literal non-negative Python int, e.g. bernoulli(10).","If n comes from a JAX array, convert with int(n) (or .item()) before calling, outside jit.","Mark n as a static_argnums/static_argnames when wrapping bernoulli in jit.","Ensure the value is not negative before calling; clamp or validate upstream."],"exampleFix":"// before\nf = jax.jit(lambda n: jax.scipy.special.bernoulli(n))\nf(jnp.array(6))\n\n// after\nf = jax.jit(lambda n: jax.scipy.special.bernoulli(n), static_argnums=0)\nf(6)  # plain Python int","handlingStrategy":"validation","validationCode":"import operator\nn = int(jax.device_get(n)) if isinstance(n, jax.Array) else n\nassert isinstance(n, int) and n >= 0, \"n must be a non-negative int\"","typeGuard":"def is_valid_bernoulli_n(n) -> bool:\n    return isinstance(n, (int, np.integer)) and n >= 0","tryCatchPattern":null,"preventionTips":["Never pass traced values as n; mark it static in jit.","Convert array n via int(n.item()) before calling."],"tags":["jax","scipy","bernoulli","static-argument","input-validation"],"backgroundTag":"jax-static-shape-requirement","analyzedSha":"1e1c6a8fc06dfcd1247076ec5cae4640cea5d7bb","analyzedAt":"2026-08-27T09:53:25.647Z","schemaVersion":2},"datasetVersion":"2026-08-27T13:17:12.746Z"}