You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
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
Found while triaging #992 (the original report there — that a query does not crop the annotating table — does not reproduce; an annotating table is cropped correctly on generated data). While building the MWE, adding a second, unrelated table to the object that has no spatialdata_attrs (e.g. an AnnData used only to carry obsm['spatial'] coordinates, never passed through TableModel.parse()) makes bounding_box_query(..., filter_table=True) (the default) crash for the entire object, even though the query does not touch that table at all. The same code path (_get_filtered_or_unfiltered_tables) is shared by polygon_query, so it is affected too.
Severity (agent's assessment): medium — a valid (if unusual) SpatialData object makes every bounding-box/polygon query crash
Where:src/spatialdata/_core/query/_utils.py::_get_filtered_or_unfiltered_tables (unconditionally calls _filter_table_by_elements on every table in sdata.tables) → src/spatialdata/_core/query/relational_query.py::_filter_table_by_elements → src/spatialdata/models/models.py::get_table_keys, which raises ValueError: No spatialdata_attrs key found in table.uns for a table that was never parsed with TableModel.parse()/has no annotation metadata.
Expected behaviour
A table that has no spatialdata annotation metadata should either be treated as "not annotating anything" and passed through unfiltered (or dropped, with a warning), not crash the whole query. At minimum the ValueError from get_table_keys should be caught in _filter_table_by_elements/_get_filtered_or_unfiltered_tables.
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",# ]# ///"""#992: 'query.bounding_box not cropping the table'. With generated data: a table that annotates the queried shapesIS cropped. Side finding: if the SpatialData object also contains an orphan table (no annotation metadata, e.g. onethat only carries obsm['spatial']), bounding_box_query(filter_table=True) crashes instead of skipping it."""importwarningsimportnumpyasnpimportpandasaspdimportgeopandasasgpdfromanndataimportAnnDatafromshapely.geometryimportPointfromspatialdataimportSpatialDatafromspatialdata.modelsimportShapesModel, TableModelwarnings.simplefilter("ignore")
shapes=ShapesModel.parse(gpd.GeoDataFrame({"geometry": [Point(2050, 2050), Point(5000, 5000)], "radius": [10.0, 10.0]}, index=[0, 1]))
obs=pd.DataFrame({"region": pd.Categorical(["cells"] *2), "instance_id": [0, 1]})
annotating=TableModel.parse(AnnData(X=np.zeros((2, 1)), obs=obs), region="cells", region_key="region", instance_key="instance_id")
kwargs=dict(min_coordinate=[2000, 2000], max_coordinate=[2200, 2200], axes=("x", "y"), target_coordinate_system="global")
crop=SpatialData(shapes={"cells": shapes}, tables={"annotating": annotating}).query.bounding_box(**kwargs)
print("annotating table only -> tables after query:", {k: v.n_obsfork, vincrop.tables.items()}, "(cropped from 2 to 1 row)")
orphan=AnnData(X=np.zeros((2, 1)), obs=pd.DataFrame(index=["a", "b"]))
orphan.obsm["spatial"] =np.array([[2050, 2050], [5000, 5000]])
sdata=SpatialData(shapes={"cells": shapes}, tables={"annotating": annotating, "orphan": orphan})
try:
crop=sdata.query.bounding_box(**kwargs)
print("with an additional orphan table -> tables after query:", {k: v.n_obsfork, vincrop.tables.items()})
side_bug=FalseexceptExceptionase: # noqa: BLE001print("with an additional orphan table ->", type(e).__name__, str(e)[:110])
side_bug=Trueprint("VERDICT: NOT REPRODUCED for the reported symptom (an annotating table is cropped)"+ ("; SIDE FINDING: an orphan table makes bounding_box_query(filter_table=True) crash"ifside_bugelse""))
Observed output
annotating table only -> tables after query: {'annotating': 1} (cropped from 2 to 1 row)
with an additional orphan table -> ValueError No spatialdata_attrs key found in table.uns, therefore, no table keys found. Please parse the table.
VERDICT: NOT REPRODUCED for the reported symptom (an annotating table is cropped); SIDE FINDING: an orphan table makes bounding_box_query(filter_table=True) crash
Possible fix direction (unverified)
Wrap the get_table_keys(table) call inside _filter_table_by_elements (or the loop in _get_filtered_or_unfiltered_tables) in a try/except ValueError, treating a table without spatialdata_attrs as not matching any element (return None/skip it), optionally with a warning.
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).
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
spatialdatacode base. It has not been verified or triaged by a human yet; theneeds: triagelabel 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
Found while triaging #992 (the original report there — that a query does not crop the annotating table — does not reproduce; an annotating table is cropped correctly on generated data). While building the MWE, adding a second, unrelated table to the object that has no
spatialdata_attrs(e.g. anAnnDataused only to carryobsm['spatial']coordinates, never passed throughTableModel.parse()) makesbounding_box_query(..., filter_table=True)(the default) crash for the entire object, even though the query does not touch that table at all. The same code path (_get_filtered_or_unfiltered_tables) is shared bypolygon_query, so it is affected too.Severity (agent's assessment): medium — a valid (if unusual) SpatialData object makes every bounding-box/polygon query crash
Where:
src/spatialdata/_core/query/_utils.py::_get_filtered_or_unfiltered_tables(unconditionally calls_filter_table_by_elementson every table insdata.tables) →src/spatialdata/_core/query/relational_query.py::_filter_table_by_elements→src/spatialdata/models/models.py::get_table_keys, which raisesValueError: No spatialdata_attrs key found in table.unsfor a table that was never parsed withTableModel.parse()/has no annotation metadata.Expected behaviour
A table that has no spatialdata annotation metadata should either be treated as "not annotating anything" and passed through unfiltered (or dropped, with a warning), not crash the whole query. At minimum the
ValueErrorfromget_table_keysshould be caught in_filter_table_by_elements/_get_filtered_or_unfiltered_tables.Reproduction
Save as
repro.pyand runuv run repro.py(the PEP 723 header pinsspatialdatato the commit the bug was found on; replace the URL fragment with@mainto test the current main branch).Observed output
Possible fix direction (unverified)
Wrap the
get_table_keys(table)call inside_filter_table_by_elements(or the loop in_get_filtered_or_unfiltered_tables) in atry/except ValueError, treating a table withoutspatialdata_attrsas not matching any element (returnNone/skip it), optionally with a warning.Environment
uv run repro.pywith the PEP 723 metadata in the script (fresh, isolated environment;spatialdatabuilt frommain@ 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).Possibly related issues
#992
Automatically generated; discovered by an AI agent (Claude) and not yet reviewed by a human.