Skip to content

fix(batch): derive has_errors from errors - #2120

Closed
g-despot wants to merge 1 commit into
mainfrom
fix/batch-has-errors-2107
Closed

fix(batch): derive has_errors from errors#2120
g-despot wants to merge 1 commit into
mainfrom
fix/batch-has-errors-2107

Conversation

@g-despot

@g-despot g-despot commented Aug 6, 2026

Copy link
Copy Markdown
Collaborator

has_errors is a stored field on BatchObjectReturn, set by hand at each construction site. The server-side-batching receive loop never sets it, and __add__ only ORs the flags together, so accumulating partial results could never flip it: data.ingest() and batch.stream() returned a populated errors dict alongside has_errors=False. insert_many was never affected, as it already passes the flag correctly.

__post_init__ now derives the flag from errors on both BatchObjectReturn and BatchReferenceReturn, so an instance cannot be constructed claiming success while carrying errors. The or keeps the change widening-only, so an explicitly passed True is preserved.

Tests cover both classes plus the ingest, async ingest and stream paths against a mock server. All seven new assertions fail without the change.

Fixes #2107

@vaibzde reported the same trace on the issue and proposed a per-call-site patch. This fixes it at the shared seam instead, so a future construction site cannot reintroduce it.

BatchObjectReturn.has_errors is a stored field set by hand at each
construction site. The server-side-batching receive loop never sets it,
and __add__ only ORs the flags together, so accumulating partial results
could never flip it: data.ingest() and batch.stream() returned a
populated errors dict alongside has_errors=False.

Derive the flag in __post_init__ on BatchObjectReturn and
BatchReferenceReturn so an instance cannot be constructed claiming
success while carrying errors.

Fixes #2107

@orca-security-eu orca-security-eu Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Orca Security Scan Summary

Status Check Issues by priority
Passed Passed Infrastructure as Code high 0   medium 0   low 0   info 0 View in Orca
Passed Passed SAST high 0   medium 0   low 0   info 0 View in Orca
Passed Passed Secrets high 0   medium 0   low 0   info 0 View in Orca
Passed Passed Vulnerabilities high 0   medium 0   low 0   info 0 View in Orca

Copilot AI 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.

Pull request overview

Ensures batch result objects can’t report has_errors=False while carrying populated errors, fixing the inconsistent behavior observed on the server-side batching ingest path (data.ingest()), and adding regression coverage for both sync/async and streaming paths.

Changes:

  • Derive has_errors from errors in BatchObjectReturn and BatchReferenceReturn via __post_init__.
  • Add unit tests validating has_errors derivation and accumulation behavior for both return types.
  • Extend mock-server tests to cover partial-failure behavior for data.ingest() (sync/async) and batch.stream().

Reviewed changes

Copilot reviewed 3 out of 3 changed files in this pull request and generated 3 comments.

File Description
weaviate/collections/classes/batch.py Derives has_errors from errors during dataclass initialization for object/reference batch return types.
test/collection/test_batch.py Adds unit tests for has_errors behavior on construction and via __add__.
mock_tests/test_batch.py Adds mock gRPC service + tests to validate partial failures set has_errors on ingest/stream (sync + async).

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment on lines +74 to +76
err = _error_object(1)
result = BatchObjectReturn()
result += BatchObjectReturn(_all_responses=[uuid.uuid4()], uuids={0: uuid.uuid4()})
Comment on lines +219 to +221
def __post_init__(self) -> None:
self.has_errors = self.has_errors or len(self.errors) > 0

Comment on lines +290 to +292
def __post_init__(self) -> None:
self.has_errors = self.has_errors or len(self.errors) > 0

@codecov-commenter

Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 88.41%. Comparing base (95b5d76) to head (f8aecd5).
⚠️ Report is 31 commits behind head on main.

Additional details and impacted files
@@            Coverage Diff             @@
##             main    #2120      +/-   ##
==========================================
+ Coverage   86.64%   88.41%   +1.76%     
==========================================
  Files         300      302       +2     
  Lines       23172    23360     +188     
==========================================
+ Hits        20077    20653     +576     
+ Misses       3095     2707     -388     

☔ View full report in Codecov by Harness.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

@g-despot

g-despot commented Aug 6, 2026

Copy link
Copy Markdown
Collaborator Author

Closing in favour of #2115, which was opened first by @vaibzde for the same issue. The implementation from this PR has been pushed onto that branch, so nothing is lost — see #2115 (comment).

@g-despot g-despot closed this Aug 6, 2026
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.

data.ingest(): BatchObjectReturn.has_errors stays False when errors is populated (and batch.failed_objects is empty)

3 participants