Skip to content

[BUG]: reject operators as top-level where keys#7448

Open
chuenchen309 wants to merge 1 commit into
chroma-core:mainfrom
chuenchen309:fix/validate-where-toplevel-operator-keys
Open

[BUG]: reject operators as top-level where keys#7448
chuenchen309 wants to merge 1 commit into
chroma-core:mainfrom
chuenchen309:fix/validate-where-toplevel-operator-keys

Conversation

@chuenchen309

Copy link
Copy Markdown

Description of changes

validate_where already rejects $contains/$not_contains when they appear as a top-level where key — a spot where a metadata field name or a logical operator ($and/$or) is expected. That guard exists precisely to catch the common typo of writing an operator where a field name belongs.

The remaining query operators leaked through, though:

from chromadb.api.types import validate_where

validate_where({"$contains": "x"})   # ValueError (correct)
validate_where({"$in": [1, 2, 3]})   # silently ACCEPTED  ❌
validate_where({"$gt": 5})           # silently ACCEPTED  ❌
validate_where({"$eq": 5})           # silently ACCEPTED  ❌

Two things combined to let them slip:

  • a scalar operand (e.g. {"$gt": 5}) satisfied the value type-check (int is allowed), and no later branch handled the operator-as-key case, so the function returned normally;
  • $in/$nin were explicitly excluded from that value type-check (and key != "$in" and key != "$nin"), which is exactly what suppressed the type error their list operand would otherwise have raised.

So a user who forgets the field name — collection.get(where={"$in": [1, 2]}) instead of where={"field": {"$in": [1, 2]}} — got no client-side error, unlike the analogous {"$contains": ...} typo which is caught with a clear message.

This PR extends the existing top-level-key guard to the full operator set ($gt $gte $lt $lte $ne $eq $in $nin $contains $not_contains) and drops the now-dead $in/$nin exclusion. Operators inside a field expression ({"field": {"$in": [...]}}) and $and/$or keys are unaffected.

Test plan

Added test_validate_where_rejects_top_level_operator_key (parametrized over all ten operators) and test_validate_where_accepts_operator_in_field_expression to chromadb/test/api/test_types.py.

  • On main the eight previously-leaking operators fail the new rejection assertions; with this change all ten are rejected and legitimate field/$and/$or filters still validate.
  • pytest chromadb/test/api/test_types.py → 13 passed.
  • black --check and flake8 clean on both files.

Authored with assistance from Claude Code (Anthropic). Bug, fix, and tests were reviewed and verified locally by the contributor.

validate_where already rejects $contains/$not_contains when used as a
top-level where key (where a metadata field name or $and/$or is
expected), but the other query operators ($gt, $gte, $lt, $lte, $ne,
$eq, $in, $nin) slipped through: a scalar operand passed the value
type check, and $in/$nin were explicitly excluded from it, so a
malformed filter like {"$in": [1, 2]} (field name forgotten) was
silently accepted instead of raising the same clear ValueError.

Extend the existing top-level-key guard to the full operator set and
drop the now-dead $in/$nin exclusion from the value type check. Query
operators inside a field expression ({"field": {"$in": [...]}}) and
$and/$or logical keys are unaffected.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>

@claude claude Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Claude Code Review

This pull request is from a fork — automated review is disabled. A repository maintainer can comment @claude review to run a one-time review.

@github-actions

Copy link
Copy Markdown

Reviewer Checklist

Please leverage this checklist to ensure your code review is thorough before approving

Testing, Bugs, Errors, Logs, Documentation

  • Can you think of any use case in which the code does not behave as intended? Have they been tested?
  • Can you think of any inputs or external events that could break the code? Is user input validated and safe? Have they been tested?
  • If appropriate, are there adequate property based tests?
  • If appropriate, are there adequate unit tests?
  • Should any logging, debugging, tracing information be added or removed?
  • Are error messages user-friendly?
  • Have all documentation changes needed been made?
  • Have all non-obvious changes been commented?

System Compatibility

  • Are there any potential impacts on other parts of the system or backward compatibility?
  • Does this change intersect with any items on our roadmap, and if so, is there a plan for fitting them together?

Quality

  • Is this code of a unexpectedly high quality (Readability, Modularity, Intuitiveness)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant