Repository navigation
Add KD-56 and KD-57, and throw on Chroma Cloud for the filters on the documents that give the wrong records there - #127
Merged
Merged
Conversation
…pty text finds every record
…se pattern takes an empty text, which finds every record there
Laurianti
force-pushed
the
kd-regex-empty-text
branch
from
October 12, 2026 16:22
be28bf2 to
b16e9d3
Compare
…ds otherwise than Chroma, and build that check only on Chroma Cloud
There was a problem hiding this comment.
🟡 Changes recommended
Regex evaluation timeouts currently escape as an unintended exception type instead of being handled as unverifiable patterns.
1 open finding
What changed in this PR
Adds a Chroma Cloud safeguard for KD-56 to prevent empty-matching document regexes from returning or deleting incorrect records.
Changes:
- Validates document regexes before Cloud requests.
- Adds unit and integration coverage.
- Documents KD-56 and supported alternatives.
| File | Description |
|---|---|
ChromaDB.Client/ChromaCollectionClient.cs |
Implements regex validation across reads and deletes. |
ChromaDB.Client/ChromaWhereDocumentOperator.cs |
Documents Cloud behavior on regex APIs. |
ChromaDB.Client.Tests/DocumentRegexesTests.cs |
Tests validation across operations and servers. |
ChromaDB.Client.Tests/ApiV2CompleteTests.cs |
Adds server-level KD-56 coverage. |
docs/COMPATIBILITY.md |
Records KD-56. |
docs/queries-and-filters.md |
Explains restrictions and alternatives. |
🧠 Review effort: Balanced
💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.
…NET does not match in time
… crate regex, for the minimum length of a match
…or a $contains on the documents of fewer than 3 characters, which finds no record once indexed (KD-57)
AnisaHaxhialushi
approved these changes
Oct 12, 2026
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.

On Chroma Cloud two filters on the documents give the wrong records: a
$regexwhose pattern takes an empty text finds every record, and, once Chroma Cloud has indexed the records, a$containsof fewer than 3 characters finds none. This adds KD-56 and KD-57, and makes the client throw for such filters on Chroma Cloud rather than give or delete the wrong records.Measured on 12 October 2026.
$regexon a collection of three records: one without a document, one with the document""and one with"x".$regex "^x$""x""x"$regex "^$"""$regex "^""","x"$regex "^.*$""","x"$not_regex "^$""x"On Chroma Cloud the same with this client, with the Python client 1.5.9 and in plain HTTP, and the same in the Search API. A delete by filters with
$regex "^$"deleted all three records.Every element of the syntax of the Rust crate
regex, the one of Chroma, as$regexand$not_regex, in plain HTTP on 2,100 records: of 252 filters, Chroma Cloud gives the wrong records for exactly those whose pattern has a match of minimum length 0, as Chroma computes it with its parserregex-syntax. Chroma 1.5.9 gives the right records for all.$containsand$not_containswith texts of 0 to 4 characters, in plain HTTP on 2,100 records and with the Python client 1.5.9 on 2,080. Before Chroma Cloud has indexed the records all are right. Once it has indexed them, with fewer than 3 characters$containsfinds no record and$not_containsevery record, also those without a document. The characters are the Unicode code points:αβand😀are wrong,abc,αβγando wright. The Python client rejects an empty text.Before: the client sent such filters as they are. On Chroma Cloud a get, a query or a search gave the wrong records, and a delete deleted them: every record with
$regex "^$"or$not_contains "ab".Now: on Chroma Cloud, before any request, a filter on the documents throws an
ArgumentException:$regexor$not_regexwhose pattern takes an empty text, or that the client cannot read. The client reads a pattern as Chroma does, with the syntax ofregex1.12 asregex-syntax0.8 reads it: classes with ranges, nested and POSIX classes like[[:alpha:]], word boundaries like\b{start-half}, groups, flags with the verbose mode(?x), and counts. A pattern it cannot read is one that Chroma rejects.$containsor$not_containswhose text has fewer than 3 characters.This holds in
GetAsync,QueryAsync, bothDeleteAsyncandSearchAsync, also inside$and,$orandNot. The message names the filter and what is right instead:Regex("(?s).")for the records with a document that is not empty,NotRegex("(?s).")for the others, and for a short textRegexorNotRegexwith it as the pattern, likeRegex("ab"). On a single server nothing changes, and the filter is built for the check only on Chroma Cloud: an error of the filter comes from the operation, as before.Tests:
RegexMinimumLengthTests: 155 cases, every element of the syntax at docs.rs with the minimum length of a match, and what Chroma rejects; each agrees withregex-syntax0.8.10. Againstregex-syntax0.8.10 itself on 505,481 generated patterns, 158,250 of which it reads with a minimum length: the client gives 0 whereregex-syntaxgives 0 and more than 0 elsewhere, and every pattern the client cannot read is one thatregex-syntaxrejects.DocumentFiltersTests, on a fake server: 27 filters that give the wrong records on Chroma Cloud, or that the client cannot read, throw there in seven operations and send nothing; 19 filters go; every filter goes on a single server; the messages; a filter that the get rejects still fails its task.ApiV2CompleteTests.DocumentFiltersThatChromaCloudGetsWrong: on Chroma Cloud the errors, also for deletes, which delete nothing; on Chroma Cloud and on 1.5.9 what is right instead.Docs: KD-56 and KD-57 in
docs/COMPATIBILITY.md,docs/queries-and-filters.md, and the XML comments ofContains,NotContains,RegexandNotRegex.