scverse / scverse/spatialdata

aggregate(image, by=labels) crashes when the labels have no background (no zero pixels)

Open Beginner friendly
#1,230 0 comments 0 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

bug 🚨 element: labels 🏷️ method: aggregation 🔢 needs: triage priority: medium
Dominant language
Python
Stars
394
Forks
95
Avg merge
4d 3h
Merged PRs (30d)
7

Description

[!NOTE]
This whole message is AI-generated. The issue was automatically discovered and reported by an AI agent (Claude) during an autonomous bug hunt on the spatialdata code base. It has not been verified or triaged by a human yet; the needs: triage label is set so that a maintainer can confirm it. The reproduction script below was executed by the agent in an isolated environment (see Environment) and its output is pasted verbatim.

Summary

zones excludes 0 and np.insert(zones, 0, 0) unconditionally prepends 0, so when the labels contain no 0 the comparison has mismatched lengths: ValueError: operands could not be broadcast together with shapes (2,) (3,).

Severity (agent's assessment): medium — fully tessellated segmentations (Visium HD bins as labels, Voronoi, expanded masks) are common; to_circles(labels) hits the same code

Where: src/spatialdata/_core/operations/aggregate.py::_aggregate_image_by_labels (assert np.array(index == np.insert(zones, 0, 0)).all())

Expected behaviour

Aggregation works with or without a background label.

Reproduction

Save as repro.py and run uv run repro.py (the PEP 723 header pins spatialdata to the commit the bug was found on; replace the URL fragment with @main to test the current main branch).

# /// script
# requires-python = ">=3.12"
# dependencies = [
#     "spatialdata @ git+https://github.com/scverse/spatialdata.git@ccf1ea048d054b6624214bf618008a9f9ae223e0",
# ]
# ///
"""aggregate(image, by=labels) crashes when the labels contain no background (no zero pixels)."""
import warnings
import numpy as np
from spatialdata import aggregate
from spatialdata.models import Image2DModel, Labels2DModel

warnings.simplefilter("ignore")
image = Image2DModel.parse(np.array([[[1.0, 2.0], [3.0, 4.0]]]))
bug = False
for name, arr in [("with background", np.array([[0, 1], [2, 2]], dtype=np.uint16)), ("without background", np.array([[1, 1], [2, 2]], dtype=np.uint16))]:
    labels = Labels2DModel.parse(arr)
    try:
        out = aggregate(values=image, by=labels, agg_func="sum")
        print(f"labels {name:18s}: OK -> sums {out['table'].X.toarray().ravel().tolist()}")
    except Exception as e:  # noqa: BLE001
        print(f"labels {name:18s}: {type(e).__name__}: {e}")
        bug = True
print("VERDICT:", "BUG REPRODUCED" if bug else "NOT REPRODUCED")
Observed output
labels with background   : OK -> sums [2.0, 7.0]
labels without background: ValueError: operands could not be broadcast together with shapes (2,) (3,)
VERDICT: BUG REPRODUCED

Possible fix direction (unverified)

Compare index[index != 0] with zones (or drop the assertion and use the zonal-stats zones as the index).

Environment

uv run repro.py with the PEP 723 metadata in the script (fresh, isolated environment; spatialdata built from main @ ccf1ea0 (2026-08-28); Python 3.13, latest releases of the dependencies at run time: pandas 3.0, anndata 0.13, zarr 3.3, dask 2026.8, numpy 2.5, geopandas 1.1, shapely 2.1). macOS (arm64). Also reproduced in a second environment with pandas 2.3.3 / anndata 0.12.11 / numpy 2.4.4 / zarr 3.2.1.


Automatically generated; discovered by an AI agent (Claude) and not yet reviewed by a human.

Contributor guide

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Research direction

Start in src/spatialdata/_core/operations/aggregate.py at _aggregate_image_by_labels, especially the assertion comparing index with the inserted background zone. Run the provided repro.py with uv run and verify that aggregation succeeds for labels both with and without a zero-valued background, preserving the expected sums.

Written by the indexing model from the issue text.

Assessment

Tech stack
numpy, python
Domain
data
Issue type
Bug
Difficulty
2/5
Estimated time
1-3 hours
Activity status
Active
Clarity
Clearly specified
Newbie friendliness
78/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.