Skip to content

fix(chroma): version incompatibility fails silently + NoneType 'delete' crash#1452

Open
Pankajsharma99max wants to merge 1 commit into
rocketride-org:developfrom
Pankajsharma99max:fix/1405-chroma-version-compat
Open

fix(chroma): version incompatibility fails silently + NoneType 'delete' crash#1452
Pankajsharma99max wants to merge 1 commit into
rocketride-org:developfrom
Pankajsharma99max:fix/1405-chroma-version-compat

Conversation

@Pankajsharma99max

@Pankajsharma99max Pankajsharma99max commented Jul 3, 2026

Copy link
Copy Markdown

Fixes #1405

list_collections()'s return shape differs across chromadb client versions: newer clients (>=0.6) return a list of collection name strings, older clients (<0.6) return a list of Collection objects exposing .name. _doesCollectionExist compared self.collection (a str) directly against the raw list, which only worked for the string-returning shape -- against an older server (e.g. Chroma 0.5.18) it silently evaluated to "collection does not exist" even when it did, and a raw client/server incompatibility during list_collections() (e.g. KeyError('_type')) propagated as an opaque error with no indication of the real cause.

Downstream, flush() called self.collectionObj.delete(...) / .upsert(...) without checking whether collectionObj had actually been resolved, so a prior silent failure surfaced later as an opaque AttributeError: 'NoneType' object has no attribute 'delete' instead of an actionable message -- appearing to the user as "0 done, 1 error" during ingestion with no clue why, and downstream chat systems then answering from training data instead of indexed content.

Fix

  • Normalize list_collections() results to a set of names regardless of whether the client returns strings or Collection-like objects.
  • Wrap list_collections() failures with a message naming the host/port and pointing at a likely version mismatch, instead of letting a raw KeyError propagate.
  • Fail fast in flush() with a clear, actionable error when the collection was never resolved, instead of letting it crash deep inside a per-chunk write.

A hard client/server version gate was intentionally left out of scope -- that's a call for maintainers who know the actual supported compatibility matrix. This PR fixes the underlying behavioral defect and makes failures surface clearly, which resolves the reported crash and silent-failure symptoms directly.

Testing

  • Added nodes/test/chroma/test_collection_version_compat.py (7 new tests) covering both the version-shape bug and the flush() guard.
  • Verified (locally, by reverting the fix) that these tests fail against the pre-fix code with exactly the symptoms described in the issue (assert False is True on the version-shape test; raw '_type' and 'NoneType' object has no attribute 'delete' messages on the other two), and pass after the fix.
  • ruff check / ruff format --diff clean on all changed files.

Summary by CodeRabbit

  • Bug Fixes
    • Improved collection detection across Chroma version differences, so existing collections are recognized more reliably.
    • Added clearer error messages when collection lookup fails or when chunk ingestion can’t proceed because the collection isn’t initialized.
    • Prevented a downstream opaque NoneType/attribute error by failing fast with actionable feedback.
  • Tests
    • Added regression coverage for collection existence checks across multiple Chroma response shapes.
    • Added a test for the new fail-fast behavior during chunk ingestion.

…e' crash

Fixes rocketride-org#1405

`list_collections()`'s return shape differs across chromadb client
versions: newer clients (>=0.6) return a list of collection name strings,
older clients (<0.6) return a list of Collection objects exposing `.name`.
`_doesCollectionExist` compared `self.collection` (a str) directly against
the raw list, which only worked for the string-returning shape -- against
an older server it silently evaluated to "collection does not exist" even
when it did, and a raw client/server incompatibility during
`list_collections()` (e.g. `KeyError('_type')`) propagated as an opaque
error with no indication of the real cause.

Downstream, `flush()` called `self.collectionObj.delete(...)` /
`.upsert(...)` without checking whether `collectionObj` had actually been
resolved, so a prior silent failure surfaced later as an opaque
`AttributeError: 'NoneType' object has no attribute 'delete'` instead of an
actionable message -- appearing to the user as "0 done, 1 error" during
ingestion with no clue why.

Fix:
- Normalize `list_collections()` results to a set of names regardless of
  whether the client returns strings or Collection-like objects.
- Wrap `list_collections()` failures with a message naming the host/port
  and pointing at a likely version mismatch.
- Fail fast in `flush()` with a clear, actionable error when the
  collection was never resolved, instead of letting it crash deep inside
  a per-chunk write.

Added regression tests covering both the version-shape bug and the
flush() guard; verified they fail against the pre-fix code and pass after
the fix.
@github-actions

github-actions Bot commented Jul 3, 2026

Copy link
Copy Markdown
Contributor
🤖 Internal: Discord sync marker

Auto-managed by the Discord notification workflow. Stores the linked Discord message ID. Do not edit or delete.

@coderabbitai

coderabbitai Bot commented Jul 3, 2026

Copy link
Copy Markdown
Contributor

Review Change Stack

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: ASSERTIVE

Plan: Pro

Run ID: 79709a1f-618a-4d6d-ace2-6ce4d8217cb4

📥 Commits

Reviewing files that changed from the base of the PR and between 80c6654 and 03f286f.

📒 Files selected for processing (2)
  • nodes/src/nodes/chroma/chroma.py
  • nodes/test/chroma/test_collection_version_compat.py

📝 Walkthrough

Walkthrough

Modified Store._doesCollectionExist in chroma.py to wrap list_collections() calls with error handling and normalize returned collection identifiers across Chroma client versions. Added a guard in addChunks's flush to raise a clear error when collectionObj is unresolved. Added regression tests with stub modules.

Changes

Chroma version compatibility

Layer / File(s) Summary
Collection existence check and flush guard
nodes/src/nodes/chroma/chroma.py
_doesCollectionExist wraps list_collections() in try/except with a descriptive error and normalizes returned identifiers (strings or objects with .name); flush raises an actionable error when collectionObj is None instead of failing with an opaque NoneType error.
Regression tests and stub harness
nodes/test/chroma/test_collection_version_compat.py
New test module with fake chromadb stubs (_FakeCollectionRef, _FakeCollectionObj, _FakeHttpClient), module-loading helpers (_install_min_stubs, _scoped_stubs, _load_store_class, _bare_store), and test classes validating _doesCollectionExist across return shapes/errors and flush's guard against unresolved collectionObj.

Estimated code review effort: 2 (Simple) | ~15 minutes

Sequence Diagram(s)

sequenceDiagram
  participant Caller
  participant Store
  participant ChromaClient

  Caller->>Store: addChunks(chunks, checkCollection)
  Store->>Store: _doesCollectionExist()
  Store->>ChromaClient: list_collections()
  alt list_collections fails
    ChromaClient-->>Store: raises error
    Store-->>Caller: raise descriptive version-mismatch error
  else success
    ChromaClient-->>Store: names or objects
    Store->>Store: normalize to set of names
    Store-->>Caller: True/False
  end
  Store->>Store: flush()
  alt collectionObj is None
    Store-->>Caller: raise "not initialized" error
  else
    Store->>ChromaClient: delete/upsert
  end
Loading

Related issues: #1405 — Chroma version incompatibility fails silently and causes a NoneType delete crash; this PR adds version-normalization handling in _doesCollectionExist and a fail-fast guard in flush.

Suggested labels: bug, chroma, tests

Suggested reviewers: rocketride-org/backend-maintainers

🐰 A rabbit checked the collections twice,
Strings or objects—handled nice,
No more crashes, silent and sly,
Now errors speak before chunks die.
Tests stand guard with stubs so light. 🥕

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title clearly summarizes the Chroma version-compatibility fix and the NoneType cleanup crash.
Linked Issues check ✅ Passed The changes address the Chroma return-shape mismatch, wrap list_collections failures, and guard flush when collectionObj is unset.
Out of Scope Changes check ✅ Passed The PR stays focused on Chroma compatibility fixes and regression tests without unrelated changes.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

Pankajsharma99max added a commit to Pankajsharma99max/rocketride-server that referenced this pull request Jul 3, 2026
Fixes rocketride-org#1405 -- Chroma version incompatibility fails silently + NoneType 'delete' crash.
See PR rocketride-org#1452: rocketride-org#1452
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

module:nodes Python pipeline nodes

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Chroma version incompatibility fails silently + NoneType 'delete' crash

1 participant