Skip to content

SpatialData.write() fails for spatialdata.datasets.blobs() with ome-zarr==0.14.0 (TypeError: Expected an iterable of integers) #1090

@ArneDefauw

Description

@ArneDefauw

Summary

After rebuilding a fresh environment SpatialData.write() started failing.

The same code works in an older environment with the same spatialdata, dask, and zarr versions, but with ome-zarr==0.13.0 instead of 0.14.0.

This looks like a regression at the spatialdata / ome-zarr boundary when chunks are passed from xarray/dask to the writer.

Minimal reproducer

import os
import tempfile

from spatialdata.datasets import blobs

sdata = blobs()
out = os.path.join(tempfile.gettempdir(), "sd_blobs_write_issue.zarr")
sdata.write(out)

Observed behavior

The call to sdata.write(out) raises:

TypeError: Expected an iterable of integers. Got ((3,), (512,), (512,)) instead.

Full traceback

Traceback (most recent call last):
  File "<stdin>", line 9, in <module>
  File ".../site-packages/spatialdata/_utils.py", line 263, in wrapper
    return f(*args, **kwargs)
  File ".../site-packages/spatialdata/_core/spatialdata.py", line 1176, in write
    self._write_element(
  File ".../site-packages/spatialdata/_core/spatialdata.py", line 1229, in _write_element
    write_image(
  File ".../site-packages/spatialdata/_io/io_raster.py", line 371, in write_image
    _write_raster(
  File ".../site-packages/spatialdata/_io/io_raster.py", line 197, in _write_raster
    _write_raster_dataarray(
  File ".../site-packages/spatialdata/_io/io_raster.py", line 275, in _write_raster_dataarray
    write_single_scale_ngff(
  File ".../site-packages/ome_zarr/writer.py", line 651, in write_image
    dask_delayed_jobs = _write_pyramid_to_zarr(
  File ".../site-packages/ome_zarr/writer.py", line 754, in _write_pyramid_to_zarr
    da.to_zarr(
  File ".../site-packages/dask/array/core.py", line 4101, in to_zarr
    z = root.create_array(name=array_name, **zarr_array_kwargs)
  File ".../site-packages/zarr/core/group.py", line 2715, in create_array
    self._sync(
  File ".../site-packages/zarr/core/array.py", line 777, in _create_metadata_v3
    chunk_grid_parsed = RegularChunkGrid(chunk_shape=chunk_shape)
  File ".../site-packages/zarr/core/chunk_grids.py", line 180, in __init__
    chunk_shape_parsed = parse_shapelike(chunk_shape)
  File ".../site-packages/zarr/core/common.py", line 200, in parse_shapelike
    raise TypeError(msg)
TypeError: Expected an iterable of integers. Got ((3,), (512,), (512,)) instead.

Version comparison

Failing environment:

Python 3.12.12
spatialdata 0.7.2
ome-zarr 0.14.0
zarr 3.1.5
dask 2026.1.1

Working environment:

Python 3.12.12
spatialdata 0.7.2
ome-zarr 0.13.0
zarr 3.1.5
dask 2026.1.1

So the only relevant version difference I found between the two environments is ome-zarr.

Suspected cause

It looks like spatialdata passes xarray/dask chunk metadata in the form returned by .chunks, i.e. a tuple of tuples:

((3,), (512,), (512,))

In spatialdata/_io/io_raster.py, raster_data.chunks is forwarded into storage_options["chunks"]:

chunks = raster_data.chunks
...
storage_options = {"chunks": chunks}

Then in ome_zarr/writer.py, that value is forwarded into zarr_array_kwargs["chunks"]:

chunks_opt = options.pop("chunks", None)
...
zarr_array_kwargs["chunks"] = chunks_opt

But zarr expects a flat chunk shape like:

(3, 512, 512)

not the dask chunk grid:

((3,), (512,), (512,))

Expected behavior

blobs().write(path) should succeed, or the chunk metadata should be normalized before being passed to Zarr.

Workaround

Pinning ome-zarr==0.13.0 avoids the problem in my setup.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions