{"record":{"id":"b890bc125fa20e0e","repo":"jax-ml/jax","slug":"convolution-dimension-numbers-cannot-have-dupl","errorCode":null,"errorMessage":"convolution dimension_numbers[{}] cannot have duplicate characters, got {}.","messagePattern":"convolution dimension_numbers\\[(.+?)\\] cannot have duplicate characters, got (.+?)\\.","errorType":"validation","errorClass":"TypeError","httpStatus":null,"severity":"error","filePath":"jax/_src/lax/convolution.py","lineNumber":1003,"sourceCode":"    return ConvDimensionNumbers(lhs_spec, rhs_spec, out_spec)\n  else:\n    msg = \"convolution dimension_numbers must be tuple/list or None, got {}.\"\n    raise TypeError(msg.format(type(dimension_numbers)))\n\n\ndef conv_general_permutations(dimension_numbers):\n  \"\"\"Utility for convolution dimension permutations relative to Conv HLO.\"\"\"\n  lhs_spec, rhs_spec, out_spec = dimension_numbers\n  lhs_char, rhs_char, out_char = charpairs = (\"N\", \"C\"), (\"O\", \"I\"), (\"N\", \"C\")\n  for i, (a, b) in enumerate(charpairs):\n    if not dimension_numbers[i].count(a) == dimension_numbers[i].count(b) == 1:\n      msg = (\"convolution dimension_numbers[{}] must contain the characters \"\n             \"'{}' and '{}' exactly once, got {}.\")\n      raise TypeError(msg.format(i, a, b, dimension_numbers[i]))\n    if len(dimension_numbers[i]) != len(set(dimension_numbers[i])):\n      msg = (\"convolution dimension_numbers[{}] cannot have duplicate \"\n             \"characters, got {}.\")\n      raise TypeError(msg.format(i, dimension_numbers[i]))\n  if not (set(lhs_spec) - set(lhs_char) == set(rhs_spec) - set(rhs_char) ==\n          set(out_spec) - set(out_char)):\n    msg = (\"convolution dimension_numbers elements must each have the same \"\n           \"set of spatial characters, got {}.\")\n    raise TypeError(msg.format(dimension_numbers))\n\n  def getperm(spec, charpair):\n    spatial = (i for i, c in enumerate(spec) if c not in charpair)\n    if spec is not rhs_spec:\n      spatial = sorted(spatial, key=lambda i: rhs_spec.index(spec[i]))\n    return (spec.index(charpair[0]), spec.index(charpair[1])) + tuple(spatial)\n\n  lhs_perm, rhs_perm, out_perm = map(getperm, dimension_numbers, charpairs)\n  return lhs_perm, rhs_perm, out_perm\n\n\ndef _conv_general_vjp_lhs_padding(\n    in_shape, window_dimensions, window_strides, out_shape, padding,","sourceCodeStart":985,"sourceCodeEnd":1021,"githubUrl":"https://github.com/jax-ml/jax/blob/1e1c6a8fc06dfcd1247076ec5cae4640cea5d7bb/jax/_src/lax/convolution.py#L985-L1021","documentation":"Beyond containing the right special characters, each layout string must not repeat any character (its length must equal the number of distinct characters). Duplicate characters make the permutation ambiguous and raise this TypeError.","triggerScenarios":"Passing a layout like 'NCHH' or 'OIWW' where a spatial character repeats instead of using distinct spatial letters.","commonSituations":"3D convs where devs reuse 'H' for both height and depth; auto-generated layout strings from loops that collide on letters.","solutions":["Use distinct spatial characters per axis, e.g. 'NCHWD' / 'OIHWD' for 3D convs","Construct layouts programmatically from the known rank to guarantee uniqueness"],"exampleFix":"# before\ndn = lax.conv_dimension_numbers(x.shape, w.shape, ('NCHHH', 'OIHHH', 'NCHHH'))\n# after\ndn = lax.conv_dimension_numbers(x.shape, w.shape, ('NCHWD', 'OIHWD', 'NCHWD'))","handlingStrategy":"validation","validationCode":"assert all(len(s) == len(set(s)) for s in dimension_numbers), 'duplicate characters in layout'","typeGuard":"def no_dup_chars(dn) -> bool:\n    return all(len(s) == len(set(s)) for s in dn)","tryCatchPattern":null,"preventionTips":["Use distinct spatial letters (H, W, D) per axis in 3D convs"],"tags":["jax","convolution","dimension-numbers","validation"],"backgroundTag":"invalid-argument-format","analyzedSha":"1e1c6a8fc06dfcd1247076ec5cae4640cea5d7bb","analyzedAt":"2026-08-27T09:53:25.647Z","schemaVersion":2},"datasetVersion":"2026-08-27T13:17:12.746Z"}