Skip to content

fix: resolve Pydantic delta serialization warnings in agent streaming#2005

Merged
Vchen7629 merged 7 commits into
mainfrom
chat-message-pydantic-field-warning-log-fix
Jul 6, 2026
Merged

fix: resolve Pydantic delta serialization warnings in agent streaming#2005
Vchen7629 merged 7 commits into
mainfrom
chat-message-pydantic-field-warning-log-fix

Conversation

@Vchen7629

@Vchen7629 Vchen7629 commented Jul 2, 2026

Copy link
Copy Markdown
Collaborator

Summary

Port of PR #1924 to target main branch instead of release-0.5.1. Fixes #1821. Resolves repeated PydanticSerializationUnexpectedValue warnings logged for every streamed chat chunk. Langflow's /response SSE always wraps text deltas as {"content": "..."} for every provider, but the openai SDK's response event models declare delta: str. When chunk.model_dump() runs, Pydantic's serializer checks delta against that str type, finds a dict, and logs a warning for every chunk which pollutes the openrag-backend logs

Changes

  • exclude delta from model_dump()'s serialization (which is what triggers the type-check warning), then reattach the raw, unvalidated delta value back onto the resulting dict. Output shape sent to the frontend/SDK is unchanged and only the noisy serializer warning is avoided.
  • Added a comment above my agent.py changes explaining why and when this workaround can be removed.
  • Added a simple regression unit test to verify that the pydantic warning isnt being raised and the fields to be expected

Summary by CodeRabbit

  • Bug Fixes

    • Improved streaming response handling for structured delta chunks to prevent serialization warnings while preserving the original delta content.
  • Tests

    • Added unit tests to verify delta serialization behavior when excluding the delta field: no warnings are emitted, and the dumped output retains the original delta content and event type.

@Vchen7629 Vchen7629 requested a review from lucaseduoli July 2, 2026 19:23
@github-actions github-actions Bot added backend 🔷 Issues related to backend services (OpenSearch, Langflow, APIs) tests bug 🔴 Something isn't working. labels Jul 2, 2026
@coderabbitai

coderabbitai Bot commented Jul 2, 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: CHILL

Plan: Pro

Run ID: 99ed5438-6b7e-454b-bf46-f924b8e5d663

📥 Commits

Reviewing files that changed from the base of the PR and between f966225 and b19f1ce.

📒 Files selected for processing (1)
  • tests/unit/test_agent_stream_delta.py
🚧 Files skipped from review as they are similar to previous changes (1)
  • tests/unit/test_agent_stream_delta.py

Walkthrough

async_response_stream now serializes chunks with model_dump(exclude={"delta"}) and then restores chunk.delta. New unit tests cover warning behavior for direct dumping and the preserved delta shape with exclusion.

Changes

Delta serialization fix

Layer / File(s) Summary
Chunk serialization fix
src/agent.py
model_dump() now excludes delta, and the original chunk.delta value is reattached afterward when present.
Delta serialization tests
tests/unit/test_agent_stream_delta.py
Adds a mismatched Pydantic delta event fixture and tests warning behavior for direct dumping versus excluded dumping with delta restoration.

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

Suggested labels: bug

🚥 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 matches the main change: fixing Pydantic serialization warnings in agent streaming.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch chat-message-pydantic-field-warning-log-fix

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.

@github-actions github-actions Bot added bug 🔴 Something isn't working. and removed bug 🔴 Something isn't working. labels Jul 2, 2026

@coderabbitai coderabbitai 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.

🧹 Nitpick comments (1)
tests/unit/test_agent_stream_delta.py (1)

13-25: 📐 Maintainability & Code Quality | 🔵 Trivial | 💤 Low value

Solid regression test. Optionally strengthen it by also asserting that the plain chunk.model_dump() (without exclude) actually triggers the warning, proving this test would catch a regression if the workaround becomes unnecessary or ineffective.

Optional companion assertion
     with warnings.catch_warnings():
         warnings.simplefilter("error")
 
         chunk_data = chunk.model_dump(exclude={"delta"})
         chunk_data["delta"] = chunk.delta
 
     assert chunk_data["delta"] == {"content": "Hello"}
     assert chunk_data["type"] == "response.output_text.delta"
+
+
+def test_model_dump_without_exclude_raises_the_warning() -> None:
+    chunk = FakeTextDeltaEvent.model_construct(
+        delta={"content": "Hello"}, type="response.output_text.delta"
+    )
+    with warnings.catch_warnings():
+        warnings.simplefilter("error")
+        with pytest.raises(UserWarning):
+            chunk.model_dump()
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@tests/unit/test_agent_stream_delta.py` around lines 13 - 25, The regression
test around FakeTextDeltaEvent.model_dump() should also prove the warning path
is exercised, not just the workaround. In
test_model_dump_excluding_delta_avoids_warning_and_preserves_dict_shape, add an
assertion that calling chunk.model_dump() without exclude={"delta"} raises the
expected warning, while keeping the existing excluded-dump check to verify the
fix still preserves the dict shape.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Nitpick comments:
In `@tests/unit/test_agent_stream_delta.py`:
- Around line 13-25: The regression test around FakeTextDeltaEvent.model_dump()
should also prove the warning path is exercised, not just the workaround. In
test_model_dump_excluding_delta_avoids_warning_and_preserves_dict_shape, add an
assertion that calling chunk.model_dump() without exclude={"delta"} raises the
expected warning, while keeping the existing excluded-dump check to verify the
fix still preserves the dict shape.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

Run ID: 0aecb6c6-f811-4327-ae24-eaf120d41e07

📥 Commits

Reviewing files that changed from the base of the PR and between 4f104ec and 6d93ab0.

📒 Files selected for processing (2)
  • src/agent.py
  • tests/unit/test_agent_stream_delta.py

@github-actions github-actions Bot added bug 🔴 Something isn't working. and removed bug 🔴 Something isn't working. labels Jul 2, 2026
@github-actions github-actions Bot added bug 🔴 Something isn't working. and removed bug 🔴 Something isn't working. labels Jul 2, 2026

@coderabbitai coderabbitai 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.

🧹 Nitpick comments (2)
tests/unit/test_agent_stream_delta.py (2)

18-24: 🎯 Functional Correctness | 🔵 Trivial | ⚡ Quick win

Assertion doesn't verify the warning is the expected serialization warning.

assert recorded only checks that some warning fired, not that it's the PydanticSerializationUnexpectedValue/serializer warning this test is meant to demonstrate. If an unrelated warning were emitted (e.g., a deprecation warning from another import), this assertion would still pass, masking a regression where the actual serialization warning stops firing.

🔍 Suggested tightening
     with warnings.catch_warnings(record=True) as recorded:
         warnings.simplefilter("always")
         chunk.model_dump()

-    assert recorded, "expected a serialization warning when delta has a type mismatch"
+    assert any(
+        "serializer warnings" in str(w.message) for w in recorded
+    ), "expected a Pydantic serialization warning when delta has a type mismatch"
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@tests/unit/test_agent_stream_delta.py` around lines 18 - 24, The test in
test_model_dump_without_exclusion_raises_serialization_warning only checks that
some warning was emitted, so tighten it to assert the warning is the expected
serialization warning from chunk.model_dump. Inspect the warnings captured in
recorded and verify the specific warning category/message associated with
PydanticSerializationUnexpectedValue rather than relying on assert recorded, so
the test fails if an unrelated warning appears or the serializer warning stops
firing.

13-34: 📐 Maintainability & Code Quality | 🔵 Trivial | 🏗️ Heavy lift

Tests validate Pydantic's own behavior, not the actual fix in agent.py.

Both tests independently replicate the model_dump(exclude={"delta"}) + reattach pattern instead of invoking async_response_stream (the function this PR actually changes, see src/agent.py:174-191). If a future edit to async_response_stream regresses the exclude/reattach logic (e.g., typo in the exclude key, or forgetting to reattach delta), these tests will still pass since they don't exercise that code path at all — they only prove that Pydantic's model_dump behaves as expected in isolation.

Consider adding a test that drives an actual chunk through async_response_stream (with a minimal async generator stub emitting a FakeTextDeltaEvent-like chunk) and asserts on the resulting SSE payload, in addition to (or instead of) these Pydantic-behavior-only unit tests.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@tests/unit/test_agent_stream_delta.py` around lines 13 - 34, The current
tests only assert Pydantic’s standalone `model_dump` behavior and do not cover
the actual logic changed in `async_response_stream`. Update the tests to drive a
real chunk through `async_response_stream` in `src/agent.py` using a minimal
async generator stub that yields a `FakeTextDeltaEvent`-like event, then assert
the emitted SSE payload includes the expected `delta` and `type` fields. Keep or
replace the existing `chunk`-based checks only if they directly exercise
`async_response_stream`’s exclude-and-reattach path.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Nitpick comments:
In `@tests/unit/test_agent_stream_delta.py`:
- Around line 18-24: The test in
test_model_dump_without_exclusion_raises_serialization_warning only checks that
some warning was emitted, so tighten it to assert the warning is the expected
serialization warning from chunk.model_dump. Inspect the warnings captured in
recorded and verify the specific warning category/message associated with
PydanticSerializationUnexpectedValue rather than relying on assert recorded, so
the test fails if an unrelated warning appears or the serializer warning stops
firing.
- Around line 13-34: The current tests only assert Pydantic’s standalone
`model_dump` behavior and do not cover the actual logic changed in
`async_response_stream`. Update the tests to drive a real chunk through
`async_response_stream` in `src/agent.py` using a minimal async generator stub
that yields a `FakeTextDeltaEvent`-like event, then assert the emitted SSE
payload includes the expected `delta` and `type` fields. Keep or replace the
existing `chunk`-based checks only if they directly exercise
`async_response_stream`’s exclude-and-reattach path.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

Run ID: d04191fa-b886-490e-a4d5-011a4947f40e

📥 Commits

Reviewing files that changed from the base of the PR and between 6d93ab0 and f966225.

📒 Files selected for processing (1)
  • tests/unit/test_agent_stream_delta.py

@github-actions github-actions Bot added bug 🔴 Something isn't working. and removed bug 🔴 Something isn't working. labels Jul 2, 2026
@github-actions github-actions Bot added bug 🔴 Something isn't working. and removed bug 🔴 Something isn't working. labels Jul 2, 2026
@github-actions github-actions Bot added the lgtm label Jul 3, 2026
@Vchen7629 Vchen7629 merged commit 9c97ca5 into main Jul 6, 2026
36 of 48 checks passed
@github-actions github-actions Bot deleted the chat-message-pydantic-field-warning-log-fix branch July 6, 2026 18:41
lucaseduoli added a commit that referenced this pull request Jul 7, 2026
…model option (#2031)

* fix: remediate image_scan CVEs in backend, frontend, and langflow images (#2000)

* fix light color text catergory chips in light mode (#2013)

Co-authored-by: Olfa Maslah <[email protected]>

* fix: upgraded version of docling (#1995)

* changed version of docling

* fix logs not being the correct ones

* go back to sequential building to save space

* add cache to builds

* remove single use results from docling manager

* revert single use results

* change the ray tenant id header

* added env

* changed cache to hit if no changes were made

* fix hash for cache

* style: ruff autofix (auto)

* fixed coderabbit

* style: ruff autofix (auto)

* added comment on docling manager

* style: ruff autofix (auto)

---------

Co-authored-by: autofix-ci[bot] <114827586+autofix-ci[bot]@users.noreply.github.com>

* feat: add chunk level page source (#2015)

* Changed export docling document to append page number

* update result on frontend to append page number

* document how to get page number in readmes

* Update flows/components/export_docling_document.py

Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com>

* Update flows/components/export_docling_document.py

Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com>

* fix: apply CodeRabbit auto-fixes

Fixed 1 file(s) based on 1 unresolved review comment.

Co-authored-by: CodeRabbit <[email protected]>

* update component code

---------

Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com>
Co-authored-by: CodeRabbit <[email protected]>

* fix: error in skip duplicates functionality for folder ingest for connectors (backport of #1941) (#2018)

* fix: error in skip duplicates functionality for folder ingest for connectors 75616(#1842) (#1941)

* fix: enhance duplicate handling and indexing for connector file uploads

* style: ruff autofix (auto)

* fix: improve duplicate handling in connector sync functionality

* chore: trigger CodeRabbit

---------

Co-authored-by: autofix-ci[bot] <114827586+autofix-ci[bot]@users.noreply.github.com>
(cherry picked from commit effaf02)

* style: ruff autofix (auto)

* fix: remove duplicate test definitions from main merge

The automated merge-from-main on this branch concatenated two tests
(test_connector_processor_indexes_cleaned_filename,
test_langflow_connector_processor_uses_cleaned_filename) that already
existed under both names, tripping ruff F811. Keep one copy of each,
preferring the version wired with connector_id_exists=True to match
current check_document_exists behavior.

---------

Co-authored-by: autofix-ci[bot] <114827586+autofix-ci[bot]@users.noreply.github.com>

* fix: Ingestion of buckets not working right after connection is tested - CPD #75506 (#1942) (#2019)

* fix: update bucket ingestion messages for clarity and consistency

* fix: guard bucket pre-selection against connection ID mismatch

The defaults query returns the first S3/COS connection regardless of active
status. Only pre-select saved bucket_names when the defaults connection_id
matches the current connector.connectionId to avoid seeding the wrong
buckets if a stale connection exists alongside the active one.



* fix: prevent defaults from overwriting user bucket selections

Two issues in the initial-selection effect:
1. hasAppliedInitial was only set when valid buckets were found, leaving the
   effect live across bucket refreshes and allowing stale defaults to overwrite
   selections made after a refetch.
2. No guard against the async race where buckets loads before initialSelectedBuckets:
   user clicks buckets, defaults arrive later and silently overwrite them.

Fix: mark hasAppliedInitial unconditionally on first evaluation, and only apply
defaults when selectedBuckets is still empty (user hasn't acted yet).



---------


(cherry picked from commit f3823b8)

Co-authored-by: Claude Sonnet 4.6 <[email protected]>

* fix: handle orphan files and return appropriate responses when syncing connectors (#1785) (#2016)

* feat: handle orphan files and return appropriate responses when syncing connectors

* feat: refactor GoogleDriveOAuth to separate required scopes and add handling for missing optional group scopes in tests

* style: ruff autofix (auto)

* feat: add handling for skipped files and warnings in task processing and UI components

---------


(cherry picked from commit aca865a)

Co-authored-by: autofix-ci[bot] <114827586+autofix-ci[bot]@users.noreply.github.com>

* fix: enhance error handling for document processing and add OCR requirement check for image files (#1859) (#2017)

* fix: enhance error handling for document processing and add OCR requirement check for image files

* style: ruff autofix (auto)

* remove clickhouse connect from langflow image (#1801)

* chore: fix ci (#1889)

* Update processors.py

* test fix

* fix ci

---------




(cherry picked from commit a286581)

Co-authored-by: autofix-ci[bot] <114827586+autofix-ci[bot]@users.noreply.github.com>
Co-authored-by: Lucas Oliveira <[email protected]>
Co-authored-by: Edwin Jose <[email protected]>

* fix: bump golang.org/x/net to v0.55.0 to remediate CVE-2026-25680 and CVE-2026-39821 (#2014)

* feat: add new design for messages and add inline references (#2020)

* update opensearch multimodal and flows to support parser, chunk size and chunk overlap

* update backend to support citations and chunk metadata

* update frontend to support citations and metadata, implement new design for assistant message

* changed the prompt for the agent

* changed the prompt for the agent

* remove hallucinated chunk references

* adjust design of citations and where popover appears

* adjusted design for message, popover and cards

* fix React Doctor picks

* fix: apply CodeRabbit auto-fixes

Fixed 5 file(s) based on 4 unresolved review comments.

Co-authored-by: CodeRabbit <[email protected]>

* style: apply biome auto-fixes [skip ci]

* updated colors in ibm mode

* fixed react doctor picks

* added correct type and validation for function calls

* remove style for message when on onboarding

* fix message not being w full

* remove search query in end of the message

* change popup to use shadcn popover

* fix coderabbit's suggestion

* increase prompt limit

---------

Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com>
Co-authored-by: CodeRabbit <[email protected]>
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>

* apply new settings on retry (#2010)

* fix: preserve HTTPException status in update_docling_preset (#1586) (#2004)

* fix: report actual synced connection count in connector_sync (#1547) (#2006)

* fix: restore LLM model values in reapply_all_settings fallback (#1587) (#2008)

* fix: prevent partial matches for exact token searches (#2003)

* fix: prevent partial matches for exact token searches (#1937)

* style: ruff autofix (auto)

* chore: remove unused json import

---------

Co-authored-by: autofix-ci[bot] <114827586+autofix-ci[bot]@users.noreply.github.com>

* fix: target agent component when updating chat flow system prompt (#2001)

* fix: target langflow agent component for system prompt update instead of provider LLM component

Signed-off-by: vchen7629 <[email protected]>

* fix: removed unused llm_provider arg from _update_langflow_system_prompt

Signed-off-by: vchen7629 <[email protected]>

* test: add unit tests for update_chat_flow_system_prompt

Signed-off-by: vchen7629 <[email protected]>

* style: ruff autofix (auto)

* fix(test): resolve flow path relative to repo root in test_langflow_agent_system_prompt

Signed-off-by: vchen7629 <[email protected]>

* style: ruff autofix (auto)

---------

Signed-off-by: vchen7629 <[email protected]>
Co-authored-by: autofix-ci[bot] <114827586+autofix-ci[bot]@users.noreply.github.com>

* fix: replaced hardcoded docker.io prefix with a env variable prefix for private repo compatibility (#2002)

Signed-off-by: vchen7629 <[email protected]>

* fix: resolve Pydantic delta serialization warnings in agent streaming (#2005)

* fix: updated agent model dump to exclude delta field

Signed-off-by: vchen7629 <[email protected]>

* test: added regression unit test to verify response field + no warnings

* style: ruff autofix (auto)

* test: added additional unit test to verify that model_dump without exclusion raises the warning

Signed-off-by: vchen7629 <[email protected]>

* style: ruff autofix (auto)

* test: tighten delta warning assertion to match specific Pydantic error

Signed-off-by: vchen7629 <[email protected]>

* style: ruff autofix (auto)

---------

Signed-off-by: vchen7629 <[email protected]>
Co-authored-by: autofix-ci[bot] <114827586+autofix-ci[bot]@users.noreply.github.com>

* fix: prevent exception details from leaking in API error responses (#2007)

* fix: removed str(e) in exceptions to prevent internals from leaking

Signed-off-by: vchen7629 <[email protected]>

* style: ruff autofix (auto)

* fix: added missing status_code

Signed-off-by: vchen7629 <[email protected]>

* style: ruff autofix (auto)

---------

Signed-off-by: vchen7629 <[email protected]>
Co-authored-by: autofix-ci[bot] <114827586+autofix-ci[bot]@users.noreply.github.com>

* Changed docling options to include local support and be shown in the Langflow tab

* style: ruff autofix (auto)

* enable ollama and delete unused file

* fix next lint

---------

Signed-off-by: vchen7629 <[email protected]>
Co-authored-by: Gautham N Pai <[email protected]>
Co-authored-by: Wallgau <[email protected]>
Co-authored-by: Olfa Maslah <[email protected]>
Co-authored-by: autofix-ci[bot] <114827586+autofix-ci[bot]@users.noreply.github.com>
Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com>
Co-authored-by: CodeRabbit <[email protected]>
Co-authored-by: Rico Furtado <[email protected]>
Co-authored-by: Claude Sonnet 4.6 <[email protected]>
Co-authored-by: Edwin Jose <[email protected]>
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
Co-authored-by: Mike Fortman <[email protected]>
Co-authored-by: hunterxtang <[email protected]>
Co-authored-by: NishadA05 <[email protected]>
Co-authored-by: Zephyrus <[email protected]>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

backend 🔷 Issues related to backend services (OpenSearch, Langflow, APIs) bug 🔴 Something isn't working. lgtm tests

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[Bug]: Chat streaming: delta field receives dict instead of string

2 participants