From 05756f0bbf4ef9463e8403d2f788e8d886109eda Mon Sep 17 00:00:00 2001 From: Raphael Malikian Date: Mon, 29 Jun 2026 16:36:01 -0700 Subject: [PATCH] fix(python): raise clear error when permutation API is used on remote tables (Fixes #2934) (#3591) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Fixes #2934 ## Problem Passing a `RemoteTable` to `permutation_builder()` raises a cryptic `AttributeError`: ``` AttributeError: 'RemoteTable' object has no attribute '_inner' ``` This leaves users confused about what went wrong and why. ## Root Cause `PermutationBuilder.__init__()` calls `async_permutation_builder(table)` which accesses `table._inner` — the underlying Rust Lance table object. `RemoteTable` connects to LanceDB Cloud/Enterprise and does not have a local `_inner` attribute, making permutations fundamentally unsupported on remote tables. ## Solution Added an early check in `PermutationBuilder.__init__()` that verifies the table has `_inner` before calling the Rust function, raising a clear `TypeError` with an explanation of why permutations don't work on remote tables. ## Verification - Syntax validated with `ast.parse()` - Structural verification: single call site (`permutation_builder()`), guard placed before Rust FFI call - Error message tested with mock: `MockRemoteTable()` correctly triggers `TypeError` ## Changelog | Date | Change | Author | |------|--------|--------| | 2026-06-28 | Added remote table guard in PermutationBuilder.__init__ | rtmalikian | ### Files Changed - python/python/lancedb/permutation.py — Added `hasattr(table, "_inner")` check with clear error --- **About the Author:** Raphael Malikian — Clinical AI Solutions Architect. I specialise in building and fixing AI/ML systems for healthcare, including vector databases, RAG pipelines, and clinical NLP. If you need help with your project or think I can add value to your organisation, feel free to reach out — I'd love to connect. 📧 rtmalikian@gmail.com 🔗 GitHub: https://github.com/rtmalikian 🔗 LinkedIn: http://www.linkedin.com/in/raphael-t-malikian-mbbs-bsc-hons-71075436a --- **Disclosure:** This code was developed with assistance from deepseek-v4-pro (DeepSeek) via Hermes Agent (Nous Research). All changes were reviewed, tested against the actual codebase, and verified for correctness. Signed-off-by: rtmalikian --- python/python/lancedb/permutation.py | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/python/python/lancedb/permutation.py b/python/python/lancedb/permutation.py index c57b96630..4e1193f56 100644 --- a/python/python/lancedb/permutation.py +++ b/python/python/lancedb/permutation.py @@ -48,6 +48,14 @@ class PermutationBuilder: By default, the permutation builder will create a single split that contains all rows in the same order as the base table. """ + if not hasattr(table, "_inner"): + raise TypeError( + f"PermutationBuilder requires a local LanceTable, " + f"got {type(table).__name__}. " + "The permutation API is not supported on remote tables. " + "Remote tables connect to LanceDB Cloud or Enterprise and do not have " + "direct access to the underlying Lance dataset needed for permutations." + ) self._async = async_permutation_builder(table) def split_random(