pola-rs/polars · error · ValueError
cannot {operation}: no storage_location found
Error message
cannot {operation}: no storage_location found What it means
Raised by the Unity Catalog integration when the table metadata returned by `get_table_info` has a null `storage_location`. Polars needs the physical cloud path (e.g. s3://bucket/...) to actually read or write table data, so `CatalogClient.scan_table` and `write_table` refuse to continue via `_extract_location_and_data_format` (client.py:746). It surfaces as a ValueError with the message 'cannot scan table: no storage_location found'. Most commonly the object exists in the catalog but is not a physical table (a view, or a foreign/share object) or was registered without a location.
Source
Thrown at py-polars/src/polars/catalog/unity/client.py:751
yield storage_update_options
if not creds:
table_id = self.table_id
msg = (
"did not receive credentials from temporary credentials API for "
f"{table_id = }"
)
raise Exception(msg) # noqa: TRY002
yield creds, expiry
def _extract_location_and_data_format(
table_info: TableInfo, operation: str
) -> tuple[str, DataSourceFormat]:
if table_info.storage_location is None:
msg = f"cannot {operation}: no storage_location found"
raise ValueError(msg)
if table_info.data_source_format is None:
msg = f"cannot {operation}: no data_source_format found"
raise ValueError(msg)
return table_info.storage_location, table_info.data_source_format
View on GitHub (pinned to df599052da)
Solutions
- Check the object type: run `SHOW TABLES`/`DESCRIBE TABLE EXTENDED` or `client.get_table_info(...)` and inspect `table_info.table_type` and `table_info.storage_location` before scanning
- If it is a view, resolve its definition and scan the underlying base table instead
- Re-register/recreate the table with an explicit LOCATION (ALTER TABLE ... SET LOCATION or CREATE TABLE ... LOCATION) if the metadata is genuinely missing it
- If using Delta Sharing, fetch the shared table through a supported path rather than the catalog scan API
Example fix
# before
lf = catalog.scan_table("main", "sales", "daily_revenue_view") # it's a view -> ValueError
# after
info = catalog.get_table_info("main", "sales", "daily_revenue_view")
if info.storage_location is None:
raise SystemExit(f"{info.table_type} has no storage; resolve the base table")
lf = catalog.scan_table("main", "sales", "daily_revenue_base") Defensive patterns
Strategy: validation
Validate before calling
info = catalog.get_table_info(catalog_name, namespace, table_name)
if info.storage_location is None:
raise ValueError(
f"{catalog_name}.{namespace}.{table_name} ({info.table_type}) has no storage_location"
) Type guard
from polars.catalog.unity.models import TableInfo
def is_scannable_table(info: TableInfo) -> bool:
return info.storage_location is not None and info.table_type not in {"VIEW", "MATERIALIZED_VIEW"} Try / catch
try:
lf = catalog.scan_table(cat, ns, tbl)
except ValueError as e:
if "no storage_location found" in str(e):
info = catalog.get_table_info(cat, ns, tbl)
raise RuntimeError(f"{tbl} is a {info.table_type}; scan its base table instead") from e
raise Prevention
- Always fetch get_table_info first in catalog wrapper code and assert storage_location/table_type
- Treat views as metadata-only: resolve base tables before scan_table calls
- Log table_type alongside failures to make catalog-shape issues diagnosable
When it happens
Trigger: Calling `catalog.scan_table(catalog_name, namespace, table_name)` or `catalog.write_table(df, ...)` where the Unity Catalog object is a VIEW (views have no storage location), a Delta Sharing proxy table, a table created with `CREATE VIEW`/external registration without LOCATION, or an API response where the storage_location field is missing/null. Also reproduced when `table_id`/name resolution points at the wrong object type.
Common situations: Pointing scan_table at a view name instead of its underlying table; using Databricks Unity Catalog objects shared via Delta Sharing that omit the location; tables created by a metastore migration that registered metadata without a storage path; SDK/API version mismatch where the field is not deserialized.
Related errors
- cannot {operation}: no data_source_format found
- a non-HTTPS workspace_url was given ({workspace_url}). To al
- cannot apply delta_table_version for table of type {data_sou
- cannot apply delta_table_options for table of type {data_sou
- write_table: table format of {catalog_name}.{namespace}.{tab
AI-assisted analysis of pola-rs/polars@df599052da (2026-08-16).
Data as JSON: /api/errors/516b35c79101b480.
Report an issue: GitHub.