{"record":{"id":"4d83ba6d44ebd653","repo":"jax-ml/jax","slug":"nperseg-must-be-a-positive-integer","errorCode":null,"errorMessage":"nperseg must be a positive integer","messagePattern":"nperseg must be a positive integer","errorType":"exception","errorClass":"ValueError","httpStatus":null,"severity":"error","filePath":"jax/_src/scipy/signal.py","lineNumber":687,"sourceCode":"    # Check if we can broadcast the outer axes together\n    try:\n      outershape = jnp.broadcast_shapes(tuple_delete(x.shape, axis),\n                                        tuple_delete(y_arr.shape, axis))\n    except ValueError as err:\n      raise ValueError('x and y cannot be broadcast together.') from err\n\n  result_dtype = dtypes.to_complex_dtype(x.dtype)\n  freq_dtype = np.finfo(result_dtype).dtype\n\n  nperseg_int: int = 0\n  nfft_int: int = 0\n  noverlap_int: int = 0\n\n  if nperseg is not None:  # if specified by user\n    nperseg_int = core.concrete_or_error(\n        int, nperseg, \"nperseg of windowed-FFT\")\n    if nperseg_int < 1:\n      raise ValueError('nperseg must be a positive integer')\n  # parse window; if array like, then set nperseg = win.shape\n  win, nperseg_int = signal_helper._triage_segments(\n      window, nperseg if nperseg is None else nperseg_int,\n      input_length=x.shape[axis], dtype=x.dtype)\n\n  if noverlap is None:\n    noverlap_int = nperseg_int // 2\n  else:\n    noverlap_int = core.concrete_or_error(\n        int, noverlap, \"noverlap of windowed-FFT\")\n\n  if nfft is None:\n    nfft_int = nperseg_int\n  else:\n    nfft_int = core.concrete_or_error(int, nfft, \"nfft of windowed-FFT\")\n\n  # Special cases for size == 0\n  if y is None:","sourceCodeStart":669,"sourceCodeEnd":705,"githubUrl":"https://github.com/jax-ml/jax/blob/1e1c6a8fc06dfcd1247076ec5cae4640cea5d7bb/jax/_src/scipy/signal.py#L669-L705","documentation":"nperseg (segment length for windowed FFTs) must be a concrete positive integer >= 1. Zero, negatives, or non-concrete values (e.g. traced JAX scalars) raise this error, because segmenting requires static shapes under jit.","triggerScenarios":"stft(x, nperseg=0) or nperseg=-256; nperseg computed from a traced value inside jax.jit; passing a float like 256.0 that converts to a bad value.","commonSituations":"Dividing signal length by a variable number of segments that can hit zero; config math like nperseg = len(x) // nseg with nseg > len(x).","solutions":["Ensure nperseg >= 1, e.g. nperseg = max(1, nperseg)","Keep nperseg as a Python int static value, not a tracer; close over it in jit or pass via static_argnums","Guard segment-count arithmetic against zero/negative results"],"exampleFix":"// before\nnperseg = len(x) // n_segments  # can be 0\njax.scipy.signal.stft(x, nperseg=nperseg)\n// after\nnperseg = max(1, len(x) // n_segments)\njax.scipy.signal.stft(x, nperseg=nperseg)","handlingStrategy":"validation","validationCode":"nperseg = int(nperseg) if nperseg is not None else 256\nassert isinstance(nperseg, int) and nperseg >= 1","typeGuard":"def valid_nperseg(n) -> bool:\n    return isinstance(n, (int,)) and not isinstance(n, bool) and n >= 1","tryCatchPattern":null,"preventionTips":["Clamp segment math: nperseg = max(1, len(x) // nseg)","Keep nperseg a Python int under jit (static), never a tracer"],"tags":["jax","scipy","stft","nperseg","jit-tracer","argument-validation"],"backgroundTag":"invalid-segment-length","analyzedSha":"1e1c6a8fc06dfcd1247076ec5cae4640cea5d7bb","analyzedAt":"2026-08-27T09:53:25.647Z","schemaVersion":2},"datasetVersion":"2026-08-27T13:17:12.746Z"}