|
57 | 57 | sanitize_content, |
58 | 58 | ) |
59 | 59 | from .version import __version__ # noqa: E402 |
60 | | -from .backends.chroma import ChromaBackend, ChromaCollection # noqa: E402 |
| 60 | +from chromadb.errors import NotFoundError as _ChromaNotFoundError # noqa: E402 |
| 61 | + |
| 62 | +from .backends.chroma import ChromaBackend, ChromaCollection, _HNSW_BLOAT_GUARD # noqa: E402 |
61 | 63 | from .palace import ( # noqa: E402 |
62 | 64 | PalaceWriteLockTimeout, |
63 | 65 | ensure_palace_initialized, |
@@ -270,11 +272,23 @@ def _get_collection(create=False): |
270 | 272 |
|
271 | 273 | if needs_rebuild: |
272 | 274 | if create: |
273 | | - raw = client.get_or_create_collection( |
274 | | - _config.collection_name, |
275 | | - metadata={"hnsw:space": "cosine"}, |
276 | | - **ef_kwargs, |
277 | | - ) |
| 275 | + # ChromaDB 1.5.x's Rust binding SIGSEGVs when |
| 276 | + # get_or_create_collection is called with metadata that differs |
| 277 | + # from what's stored. Split into get -> except create so the |
| 278 | + # metadata-comparison codepath is skipped for existing |
| 279 | + # collections (mirrors backend-layer fix from #1262). |
| 280 | + try: |
| 281 | + raw = client.get_collection(_config.collection_name, **ef_kwargs) |
| 282 | + except _ChromaNotFoundError: |
| 283 | + raw = client.create_collection( |
| 284 | + _config.collection_name, |
| 285 | + metadata={ |
| 286 | + "hnsw:space": "cosine", |
| 287 | + "hnsw:num_threads": 1, |
| 288 | + **_HNSW_BLOAT_GUARD, |
| 289 | + }, |
| 290 | + **ef_kwargs, |
| 291 | + ) |
278 | 292 | else: |
279 | 293 | raw = client.get_collection(_config.collection_name, **ef_kwargs) |
280 | 294 | _collection_cache = ChromaCollection( |
|
0 commit comments