Skip to content

Concat with coords='different' and a non-index IndexVariable causes crash #10829

@mjwillson

Description

@mjwillson

What happened?

I was trying to concatenate two Datasets, with coords='different' meaning it will concatenate any non-matching non-index coordinates.

When one of said non-index coordinates is accidentally an IndexVariable (this ideally shouldn't happen, see #9859), we get a crash because xarray assumes it can assign to the .data attribute of a non-index coordinate.

The error is:
ValueError: Cannot assign to the .data attribute of dimension coordinate a.k.a IndexVariable 'x'. Please use DataArray.assign_coords, Dataset.assign_coords or Dataset.assign as appropriate.

What did you expect to happen?

Concatenation to succeed.

Minimal Complete Verifiable Example

# /// script
# requires-python = ">=3.11"
# dependencies = [
#   "xarray[complete]@git+https://github.com/pydata/xarray.git@main",
# ]
# ///
#
# This script automatically imports the development branch of xarray to check for issues.
# Please delete this header if you have _not_ tested this script with `uv run`!

import xarray as xr
xr.show_versions()
# your reproducer code ...

a = xr.DataArray([0, 1, 2], dims=['x'], coords={'x': [0,1,2]})
a = a.assign_coords(foo=a.x)
b = a.assign_coords(foo=xr.Variable(['x'], [0, 0, 0]))
xr.concat([b, a], dim='new', coords='different')

Steps to reproduce

See MCVE above.

MVCE confirmation

  • Minimal example — the example is as focused as reasonably possible to demonstrate the underlying issue in xarray.
  • Complete example — the example is self-contained, including all data and the text of any traceback.
  • Verifiable example — the example copy & pastes into an IPython prompt or Binder notebook, returning the result.
  • New issue — a search of GitHub Issues suggests this is not a duplicate.
  • Recent environment — the issue occurs with the latest version of xarray and its dependencies.

Relevant log output

In [66]: a = xr.DataArray([0, 1, 2], dims=['x'], coords={'x': [0,1,2]})
In [67]: a = a.assign_coords(foo=a.x)
In [68]: b = a.assign_coords(foo=xr.Variable(['x'], [0, 0, 0]))
In [69]: xr.concat([b, a], dim='new', coords='different')
---------------------------------------------------------------------------
ValueError                                Traceback (most recent call last)
Cell In[69], line 1
----> 1 xr.concat([b, a], dim='new', coords='different')

File /usr/lib/python3/dist-packages/xarray/core/concat.py:264, in concat(objs, dim, data_vars, coords, compat, positions, fill_value, join, combine_attrs, create_index_for_new_dim)
    259     raise ValueError(
    260         f"compat={compat!r} invalid: must be 'broadcast_equals', 'equals', 'identical', 'no_conflicts' or 'override'"
    261     )
    263 if isinstance(first_obj, DataArray):
--> 264     return _dataarray_concat(
    265         objs,
    266         dim=dim,
    267         data_vars=data_vars,
    268         coords=coords,
    269         compat=compat,
    270         positions=positions,
    271         fill_value=fill_value,
    272         join=join,
    273         combine_attrs=combine_attrs,
    274         create_index_for_new_dim=create_index_for_new_dim,
    275     )
    276 elif isinstance(first_obj, Dataset):
    277     return _dataset_concat(
    278         objs,
    279         dim=dim,
   (...)
    287         create_index_for_new_dim=create_index_for_new_dim,
    288     )

File /usr/lib/python3/dist-packages/xarray/core/concat.py:755, in _dataarray_concat(arrays, dim, data_vars, coords, compat, positions, fill_value, join, combine_attrs, create_index_for_new_dim)
    752             arr = arr.rename(name)
    753     datasets.append(arr._to_temp_dataset())
--> 755 ds = _dataset_concat(
    756     datasets,
    757     dim,
    758     data_vars,
    759     coords,
    760     compat,
    761     positions,
    762     fill_value=fill_value,
    763     join=join,
    764     combine_attrs=combine_attrs,
    765     create_index_for_new_dim=create_index_for_new_dim,
    766 )
    768 merged_attrs = merge_attrs([da.attrs for da in arrays], combine_attrs)
    770 result = arrays[0]._from_temp_dataset(ds, name)

File /usr/lib/python3/dist-packages/xarray/core/concat.py:545, in _dataset_concat(datasets, dim, data_vars, coords, compat, positions, fill_value, join, combine_attrs, create_index_for_new_dim)
    539     datasets = [
    540         ds.expand_dims(dim_name, create_index_for_new_dim=create_index_for_new_dim)
    541         for ds in datasets
    542     ]
    544 # determine which variables to concatenate
--> 545 concat_over, equals, concat_dim_lengths = _calc_concat_over(
    546     datasets, dim_name, dim_names, data_vars, coords, compat
    547 )
    549 # determine which variables to merge, and then merge them according to compat
    550 variables_to_merge = (coord_names | data_names) - concat_over

File /usr/lib/python3/dist-packages/xarray/core/concat.py:440, in _calc_concat_over(datasets, dim, dim_names, data_vars, coords, compat)
    437         concat_over.update(opt)
    439 process_subset_opt(data_vars, "data_vars")
--> 440 process_subset_opt(coords, "coords")
    441 return concat_over, equals, concat_dim_lengths

File /usr/lib/python3/dist-packages/xarray/core/concat.py:406, in _calc_concat_over.<locals>.process_subset_opt(opt, subset)
    401         # computed variables are not to be re-computed
    402         # again in the future
    403         for ds, v in zip(
    404             datasets[1:], computed, strict=False
    405         ):
--> 406             ds.variables[k].data = v.data
    407         break
    408 else:

File /usr/lib/python3/dist-packages/xarray/core/variable.py:2718, in IndexVariable.data(self, data)
   2716 @Variable.data.setter  # type: ignore[attr-defined]
   2717 def data(self, data):
-> 2718     raise ValueError(
   2719         f"Cannot assign to the .data attribute of dimension coordinate a.k.a IndexVariable {self.name!r}. "
   2720         f"Please use DataArray.assign_coords, Dataset.assign_coords or Dataset.assign as appropriate."
   2721     )

ValueError: Cannot assign to the .data attribute of dimension coordinate a.k.a IndexVariable 'x'. Please use DataArray.assign_coords, Dataset.assign_coords or Dataset.assign as appropriate.

Anything else we need to know?

No response

Environment

INSTALLED VERSIONS ------------------ commit: None python: 3.13.6 (main, Aug 7 2025, 10:53:54) [GCC 14.2.0] python-bits: 64 OS: Linux OS-release: 6.12.32-1rodete1-amd64 machine: x86_64 processor: byteorder: little LC_ALL: None LANG: en_US.UTF-8 LOCALE: ('en_US', 'UTF-8') libhdf5: 1.14.5 libnetcdf: 4.9.3

xarray: 999
pandas: 2.2.3
numpy: 2.2.4
scipy: 1.15.3
netCDF4: 1.7.2
pydap: None
h5netcdf: 1.6.1
h5py: 3.13.0
zarr: 3.0.6
cftime: 1.6.4
nc_time_axis: None
iris: None
bottleneck: 1.4.2
dask: None
distributed: None
matplotlib: 3.10.1+dfsg1
cartopy: None
seaborn: None
numbagg: None
fsspec: 2025.7.0
cupy: None
pint: None
sparse: None
flox: None
numpy_groupies: None
setuptools: 78.1.1
pip3: None
conda: None
pytest: 8.3.5
mypy: None
IPython: 8.35.0
sphinx: 8.1.3

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugneeds triageIssue that has not been reviewed by xarray team membertopic-combinecombine/concat/merge

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions