From 644d88ab93074d1c00ffb42178aa99e5fdfbfbda Mon Sep 17 00:00:00 2001 From: Ed_ Date: Tue, 9 Jun 2026 14:47:01 -0400 Subject: [PATCH] fix(rag): break recursion in _validate_collection_dim The wipe path called self._init_vector_store() which re-invoked _validate_collection_dim, causing infinite recursion (RecursionError) when the dim mismatch test ran with the mock embedding provider. Re-initialize the vector store INLINE after the rmtree wipe so the fresh collection is created without going through the validator again. --- src/rag_engine.py | 18 +++++++++++++++++- 1 file changed, 17 insertions(+), 1 deletion(-) diff --git a/src/rag_engine.py b/src/rag_engine.py index 9a54a1b9..b7c7c72e 100644 --- a/src/rag_engine.py +++ b/src/rag_engine.py @@ -176,6 +176,9 @@ class RAGEngine: # fails on corrupted state in chromadb 1.5.x with # "RustBindingsAPI object has no attribute bindings"). Rmtree is # reliable and re-creates a fresh empty collection. + # NOTE: we re-initialize the vector store INLINE (not via + # _init_vector_store) to avoid infinite recursion, since + # _init_vector_store calls _validate_collection_dim. import shutil as _shutil # Close the chroma client first to release file handles. Without # this, rmtree fails with WinError 32 on Windows. @@ -194,7 +197,20 @@ class RAGEngine: except Exception as e: sys.stderr.write(f"RAG: Failed to wipe chroma dir: {e}\n") sys.stderr.flush() - self._init_vector_store() + # Re-initialize the vector store inline (no recursion). + vs_config = self.config.vector_store + if vs_config.provider == 'chroma': + from src import rag_engine as _re_self + os.makedirs(db_path, exist_ok=True) + chroma_module = _get_chromadb() + if chroma_module is None: + raise ImportError("chromadb is not installed") + chromadb, _Settings = chroma_module + self.client = chromadb.PersistentClient(path=db_path) + self.collection = self.client.get_or_create_collection(name=vs_config.collection_name) + elif vs_config.provider == 'mock': + self.client = "mock" + self.collection = "mock" def is_empty(self) -> bool: if not self.config.enabled: