{"record":{"id":"7c7c1e1cda204f30","repo":"jax-ml/jax","slug":"primal-and-tangent-arguments-to-jax-jvp-must-be-tu","errorCode":null,"errorMessage":"primal and tangent arguments to jax.jvp must be tuples or lists; found {type(primals).__name__} and {type(tangents).__name__}.","messagePattern":"primal and tangent arguments to jax\\.jvp must be tuples or lists; found (.+?) and (.+?)\\.","errorType":"validation","errorClass":"TypeError","httpStatus":null,"severity":"error","filePath":"jax/_src/api.py","lineNumber":1448,"sourceCode":"    ``tangents_out`` value has the same Python tree structure and shapes as\n    ``primals_out``. If ``has_aux`` is ``True``, returns a\n    ``(primals_out, tangents_out, aux)`` tuple where ``aux``\n    is the auxiliary data returned by ``fun``.\n\n  For example:\n\n  >>> import jax\n  >>>\n  >>> primals, tangents = jax.jvp(jax.numpy.sin, (0.1,), (0.2,))\n  >>> print(primals)\n  0.09983342\n  >>> print(tangents)\n  0.19900084\n  \"\"\"\n  check_callable(fun)\n  if (not isinstance(primals, (tuple, list)) or\n      not isinstance(tangents, (tuple, list))):\n    raise TypeError(\"primal and tangent arguments to jax.jvp must be tuples or lists; \"\n                    f\"found {type(primals).__name__} and {type(tangents).__name__}.\")\n  return _jvp(fun, primals, tangents, has_aux=has_aux)\n\ndef _jvp(fun: Callable, primals, tangents, has_aux=False):\n  ps_ft = ft.flatten(primals)\n  ts_ft = ft.flatten(tangents)\n  if ps_ft.tree != ts_ft.tree:\n    raise TypeError(\"primal and tangent arguments to jax.jvp must have the same tree \"\n                    f\"structure; primals have tree structure {ps_ft.tree} whereas tangents have \"\n                    f\"tree structure {ts_ft.tree}.\")\n  for p, t in zip(ps_ft, ts_ft):\n    if not isinstance(core.typeof(p), ShapedArray): continue\n    if core.primal_dtype_to_tangent_dtype(_dtype(p)) != _dtype(t):\n      raise TypeError(\"primal and tangent arguments to jax.jvp do not match; \"\n                      \"dtypes must be equal, or in case of int/bool primal dtype \"\n                      \"the tangent dtype must be float0.\"\n                      f\"Got primal dtype {_dtype(p)} and so expected tangent dtype \"\n                      f\"{core.primal_dtype_to_tangent_dtype(_dtype(p))}, but got \"","sourceCodeStart":1430,"sourceCodeEnd":1466,"githubUrl":"https://github.com/jax-ml/jax/blob/1e1c6a8fc06dfcd1247076ec5cae4640cea5d7bb/jax/_src/api.py#L1430-L1466","documentation":"jax.jvp requires primals and tangents to be Python tuples or lists (not scalars, arrays, dicts, or other containers). This check runs before flattening and rejects any other sequence type.","triggerScenarios":"jax.jvp(f, x, t) where x is a single jnp array rather than (x,); passing generators, dicts, or numpy arrays as the primal/tangent containers.","commonSituations":"Forgetting to wrap a single argument in a tuple; refactoring from grad (single-argument style) to jvp; passing *args splats incorrectly.","solutions":["Wrap primals and tangents in tuples/lists: jax.jvp(f, (x,), (t,))","If splatting, use jax.jvp(f, *args, **kwargs)-safe patterns or build tuples explicitly","Check both containers, since either being wrong triggers the error"],"exampleFix":"# before\njax.jvp(f, x, jnp.ones_like(x))\n# after\njax.jvp(f, (x,), (jnp.ones_like(x),))","handlingStrategy":"type-guard","validationCode":"assert isinstance(primals, (tuple, list)) and isinstance(tangents, (tuple, list)), 'jvp needs tuple/list primals and tangents'","typeGuard":"def jvp_args_ok(p, t): return isinstance(p, (tuple, list)) and isinstance(t, (tuple, list))","tryCatchPattern":null,"preventionTips":["Always call jax.jvp(f, (x,), (t,)) with explicit tuples","Write a thin wrapper that normalizes containers to tuples","Code-review for bare-array jvp calls"],"tags":["jax","jvp","autodiff","api-misuse","type-error"],"backgroundTag":"invalid-argument-type","analyzedSha":"1e1c6a8fc06dfcd1247076ec5cae4640cea5d7bb","analyzedAt":"2026-08-27T09:53:25.647Z","schemaVersion":2},"datasetVersion":"2026-08-27T13:17:12.746Z"}