Repository navigation
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
dtype is a numpy/pandas dtype object (dtype('O'), StringDtype, dtype('uint16')), never the builtin type str, so the condition is always False. A uint16 labels element annotated by a table with string instance ids is accepted without the intended TypeError. The docstring also says a warning is raised while the code raises TypeError.
Severity (agent's assessment): low — dead code; a str-vs-int mismatch between table.obs[instance_key] and the element index (a classic cause of empty joins) goes unreported
Where: src/spatialdata/_core/spatialdata.py::validate_table_in_spatialdata (dtype is str or table.obs[instance_key].dtype is str)
Expected behaviour
A mismatch raises (or warns), as intended.
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",
# ]
# ///
"""SpatialData.validate_table_in_spatialdata: the instance-key dtype-mismatch TypeError can never fire (`dtype is str`)."""
import warnings
import numpy as np
import pandas as pd
from anndata import AnnData
from spatialdata import SpatialData
from spatialdata.models import Labels2DModel, TableModel
warnings.simplefilter("ignore")
labels = Labels2DModel.parse(np.array([[0, 1], [2, 3]], dtype=np.uint16)) # integer instance ids
obs = pd.DataFrame({"region": pd.Categorical(["lab"] * 3), "instance_id": ["1", "2", "3"]}) # string instance ids
table = TableModel.parse(AnnData(X=np.zeros((3, 1)), obs=obs), region="lab", region_key="region", instance_key="instance_id")
print("labels dtype:", labels.dtype, "| table instance_id dtype:", table.obs.instance_id.dtype)
try:
SpatialData(labels={"lab": labels}, tables={"t": table})
print("SpatialData constructed without the TypeError that validate_table_in_spatialdata is meant to raise")
bug = True
except TypeError as e:
print("TypeError raised as intended:", e)
bug = False
print("VERDICT:", "BUG REPRODUCED (dead code)" if bug else "NOT REPRODUCED")Observed output
labels dtype: uint16 | table instance_id dtype: str
SpatialData constructed without the TypeError that validate_table_in_spatialdata is meant to raise
VERDICT: BUG REPRODUCED (dead code)
Possible fix direction (unverified)
Use pd.api.types.is_string_dtype(...) / np.issubdtype(dtype, np.integer); align docstring and behaviour.
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.
Activity