{"record":{"id":"baae306bbd336685","repo":"jax-ml/jax","slug":"dimension-size-after-padding-is-not-at-least-0-go","errorCode":null,"errorMessage":"Dimension size after padding is not at least 0, got result shape {result}, for padding_config {padding_config} and operand shape {op_shape}","messagePattern":"Dimension size after padding is not at least 0, got result shape (.+?), for padding_config (.+?) and operand shape (.+?)","errorType":"validation","errorClass":"ValueError","httpStatus":null,"severity":"error","filePath":"jax/_src/lax/lax.py","lineNumber":7641,"sourceCode":"\ndef _pad_shape_rule(operand, padding_value, *, padding_config):\n  if np.ndim(padding_value) != 0:\n    raise ValueError(f\"padding_value must be a scalar; got {np.shape(padding_value)=}\")\n  op_shape = np.shape(operand)\n  if not len(padding_config) == np.ndim(operand):\n    raise ValueError(\"length of padding_config must equal the number of axes \"\n                     f\"of operand, got padding_config {padding_config} \"\n                     f\"for operand shape {op_shape}\")\n  if not all(i >= 0 for _, _, i in padding_config):\n    raise ValueError(\"interior padding in padding_config must be nonnegative, \"\n                     f\"got padding_config {padding_config}\")\n  result = tuple(l + h + core.dilate_dim(d, i + 1)\n                 for (l, h, i), d in zip(padding_config, op_shape))\n  if not all(d >= 0 for d in result):\n    msg = (f\"Dimension size after padding is not at least 0, \"\n           f\"got result shape {result}, for padding_config {padding_config}\"\n           f\" and operand shape {op_shape}\")\n    raise ValueError(msg)\n  return result\n\ndef _pad_sharding_rule(operand, padding_value, *, padding_config):\n  # TODO(yashkatariya): Once JAX supports uneven sharding at the top level,\n  # change this logic to `return operand.sharding` directly.\n  out_shape = _pad_shape_rule(operand, padding_value,\n                              padding_config=padding_config)\n  return slicing._get_sharding_for_varying_out_shape(\n      out_shape, operand, 'padding')\n\ndef _pad_ur_rule(operand, padding_value, *, padding_config):\n  out_unreduced = core.getu(operand)\n  kind = UnreducedKind.sum if out_unreduced else None\n  return out_unreduced, core.getr(operand), kind\n\ndef _pad_transpose(t, operand, padding_value, *, padding_config):\n  if type(t) is ad_util.Zero:\n    t_operand = ad_util.Zero(operand.aval) if ad.is_undefined_primal(operand) else None","sourceCodeStart":7623,"sourceCodeEnd":7659,"githubUrl":"https://github.com/jax-ml/jax/blob/1e1c6a8fc06dfcd1247076ec5cae4640cea5d7bb/jax/_src/lax/lax.py#L7623-L7659","documentation":"After applying each axis's (low, high, interior) padding, every output dimension is low + high + dilate(dim, interior+1); if any result is negative (low/high negative enough to over-crop), the pad shape rule raises this ValueError with the computed result shape. lax.pad permits small negative low/high but not so negative that the axis becomes negative.","triggerScenarios":"lax.pad(x, 0, [(-10, -10, 0)]) on an axis of length 4 — result dimension -16; computed negative pad widths meant to crop but overshooting.","commonSituations":"Implementing cropping via negative padding where crop exceeds the size; kernel-size arithmetic producing too-negative 'same' pads; dynamic shapes shrinking under fixed pad widths.","solutions":["Clamp negative low/high so the axis stays >= 0, or crop with slicing instead","Compute pads from actual shape: pad = min(pad, x.shape[axis]) and assert result dims >= 0","For symmetric 'same' conv padding use lax.conv_general_dilated's pad handling instead of manual lax.pad"],"exampleFix":"# before\ny = jax.lax.pad(x, 0, [(-8, -8, 0)])  # dim 4 -> -12\n# after\ncrop = min(8, x.shape[0])\ny = x[crop: x.shape[0]-crop] if crop else x","handlingStrategy":"validation","validationCode":"result = tuple(l + h + (d * (i + 1) if i else d)\n                 for (l, h, i), d in zip(padding_config, x.shape))\nassert all(d >= 0 for d in result), result","typeGuard":"def nonnegative_result(x, config) -> bool:\n    return all(l + h + (d if i == 0 else d * (i + 1)) >= 0\n               for (l, h, i), d in zip(config, x.shape))","tryCatchPattern":null,"preventionTips":["Clamp negative low/high to at most the axis size","Crop with slices; use conv ops' pad handling for 'same' padding"],"tags":["jax","pad","negative-dimension","shape-validation"],"backgroundTag":"padding-config-invalid","analyzedSha":"1e1c6a8fc06dfcd1247076ec5cae4640cea5d7bb","analyzedAt":"2026-08-27T09:53:25.647Z","schemaVersion":2},"datasetVersion":"2026-08-27T13:17:12.746Z"}