{"record":{"id":"d91310615fd2f00b","repo":"jax-ml/jax","slug":"mesh-axis-names-cannot-be-none-got-axis-names","errorCode":null,"errorMessage":"Mesh axis names cannot be None. Got: {axis_names}","messagePattern":"Mesh axis names cannot be None\\. Got: (.+?)","errorType":"validation","errorClass":"ValueError","httpStatus":null,"severity":"error","filePath":"jax/_src/mesh.py","lineNumber":275,"sourceCode":"    devices = np.array(flat_devices_tuple).reshape(device_shape)\n    devices.flags.writeable = False\n    obj = object.__new__(Mesh)\n    object.__setattr__(obj, 'devices', devices)\n    object.__setattr__(obj, 'axis_names', axis_names)\n    object.__setattr__(obj, 'axis_types', axis_types)\n    object.__setattr__(obj, 'size', size)\n    return obj\n\n  def __new__(cls, devices: np.ndarray | Sequence[xc.Device],\n              axis_names: str | Sequence[MeshAxisName],\n              axis_types: tuple[AxisType, ...] | None = None):\n    if not isinstance(devices, np.ndarray):\n      devices = np.array(devices)\n    if isinstance(axis_names, str):\n      axis_names = (axis_names,)\n    axis_names = tuple(axis_names)\n    if any(i is None for i in axis_names):\n      raise ValueError(f\"Mesh axis names cannot be None. Got: {axis_names}\")\n    if devices.ndim != len(axis_names):\n      raise ValueError(\n          \"Mesh requires the ndim of its first argument (`devices`) to equal \"\n          \"the length of its second argument (`axis_names`), but got \"\n          f\"devices.ndim == {devices.ndim} and \"\n          f\"len(axis_names) == {len(axis_names)}.\")\n\n    devices_flat = tuple(devices.flat)\n    axis_types = _normalize_axis_types(axis_names, axis_types, 'Mesh',\n                                       AxisType.Auto)\n    empty = not axis_names and devices_flat[0] is None\n    size = 0 if empty else math.prod(devices.shape)\n    return cls._create(devices_flat, devices.shape, axis_names,\n                       axis_types, size)\n\n  # No __eq__ or __hash__: interned classes use object identity.\n\n  @property","sourceCodeStart":257,"sourceCodeEnd":293,"githubUrl":"https://github.com/jax-ml/jax/blob/1e1c6a8fc06dfcd1247076ec5cae4640cea5d7bb/jax/_src/mesh.py#L257-L293","documentation":"Mesh._create converts axis_names to a tuple and rejects any None entries with ValueError. Mesh axis names are used as dict keys for shardings and resource lookups, so None names would break every downstream mapping.","triggerScenarios":"Passing axis_names containing None, e.g. Mesh(devs, ('data', None)) or a list built by zipping mismatched sequences; also Mesh(devs, (None,)) when a name variable failed to be set.","commonSituations":"Programmatic construction of mesh names from config where an optional axis (e.g. 'tensor' absent for some runs) yields None; defaulting missing config entries to None instead of skipping them.","solutions":["Filter out None axis names and reshape devices accordingly","Default missing axis names to a real name like 'singleton' or omit that axis entirely","Validate config-derived names before constructing the Mesh"],"exampleFix":"# before\nnames = ('data', maybe_tensor_name)  # maybe_tensor_name may be None\nmesh = jax.sharding.Mesh(devs.reshape(8, 1), names)\n\n# after\nnames = tuple(n for n in (base, maybe_tensor_name) if n)\nmesh = jax.sharding.Mesh(devs.reshape([d for d in devs.shape if d != 1][:len(names)] or (devs.size,)), names)","handlingStrategy":"validation","validationCode":"names = tuple(n for n in candidate_names if n is not None)\nassert all(names), 'no None axis names'","typeGuard":"def valid_axis_names(names):\n    return all(n is not None for n in names)","tryCatchPattern":null,"preventionTips":["Filter None out of config-derived names early","Use explicit defaults for optional axes instead of None"],"tags":["jax","mesh","axis-names","input-validation"],"backgroundTag":"none-value-in-collection","analyzedSha":"1e1c6a8fc06dfcd1247076ec5cae4640cea5d7bb","analyzedAt":"2026-08-27T09:53:25.647Z","schemaVersion":2},"datasetVersion":"2026-08-27T13:17:12.746Z"}