Skip to content

fix: stop default_from_dict from mutating the caller's data dict - #11931

Merged
anakin87 merged 1 commit into
deepset-ai:mainfrom
Vedant-Agarwal:fix/default-from-dict-mutates-data
Jul 9, 2026
Merged

fix: stop default_from_dict from mutating the caller's data dict#11931
anakin87 merged 1 commit into
deepset-ai:mainfrom
Vedant-Agarwal:fix/default-from-dict-mutates-data

Conversation

@Vedant-Agarwal

Copy link
Copy Markdown
Contributor

Related Issues

Proposed Changes:

default_from_dict() took a reference to data["init_parameters"] and then, while auto-deserializing nested objects, replaced the serialized sub-dicts with their live instances in place:

init_params = data.get("init_parameters", {})   # reference into the caller's dict
...
init_params[key] = Secret.from_dict(value)       # mutates data["init_parameters"] in place

So after Component.from_dict(data) (which routes through default_from_dict), the caller's data is silently corrupted — its serialized Secret / ComponentDevice / nested-component dicts are swapped for live objects. A second deserialization of the same data, or any later re-serialization / comparison, then misbehaves.

PipelineBase.from_dict already deep-copies data before deserializing precisely to avoid this; the public default_from_dict / component_from_dict utilities did not. The fix copies init_parameters before mutating it (shallow is enough — only its top-level keys are reassigned).

How did you test it?

  • Added test_component_from_dict_does_not_mutate_input, which deserializes a dict containing a serialized Secret and asserts (a) the returned component is correct and (b) the input dict is unchanged (data == deepcopy(data) taken before the call). It fails on main (the input's api_key sub-dict becomes an EnvVarSecret) and passes with the fix.
  • python -m pytest test/core/test_serialization.py → all green (23 tests).
  • ruff check / ruff format --check clean on both files.

Notes for the reviewer

Minimal one-line change at the single choke point (component_from_dict delegates here), so it covers every path. This complements #11908's dataclass-level fix by closing the same leak in the core utility.

This PR was written with the help of an AI assistant. I have reviewed the changes and run the relevant tests locally.

Checklist

  • I have read the contributors guidelines and the code of conduct.
  • Conventional commit type in the PR title (fix:).
  • I have added a unit test and documented the change.
  • I have added a release note file.

@Vedant-Agarwal
Vedant-Agarwal requested a review from a team as a code owner July 9, 2026 09:30
@Vedant-Agarwal
Vedant-Agarwal requested review from anakin87 and removed request for a team July 9, 2026 09:30
@vercel

vercel Bot commented Jul 9, 2026

Copy link
Copy Markdown

@Vedant-Agarwal is attempting to deploy a commit to the deepset Team on Vercel.

A member of the Team first needs to authorize it.

default_from_dict took a reference to data["init_parameters"] and replaced
serialized sub-objects (Secret, ComponentDevice, nested components) with their
deserialized instances in place, corrupting the caller's dict and breaking a
second deserialization of the same data. Copy init_parameters before mutating,
matching PipelineBase.from_dict which already deep-copies data to avoid this.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
@Vedant-Agarwal
Vedant-Agarwal force-pushed the fix/default-from-dict-mutates-data branch from af886f5 to 0bb1d24 Compare July 9, 2026 09:40
@github-actions

github-actions Bot commented Jul 9, 2026

Copy link
Copy Markdown
Contributor

Coverage report

Click to see where and how coverage changed

FileStatementsMissingCoverageCoverage
(new stmts)
Lines missing
  haystack/core
  serialization.py
Project Total  

This report was generated by python-coverage-comment-action

@zeweihan

zeweihan commented Jul 9, 2026

Copy link
Copy Markdown

@/tmp/gh_comment_85.md

@anakin87 anakin87 left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Thank you!

@anakin87
anakin87 merged commit 8812223 into deepset-ai:main Jul 9, 2026
24 of 25 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants