microsoft / microsoft/entrabot
efferent_copy.py: args/result dicts shared across N sink tasks and the body — sink mutation can corrupt tool return value
Nobody has claimed this yet.
- Dominant language
- Python
- Stars
- 9
- Forks
- 6
- PR merge metrics
- No merged PRs in 30d
Description
File: src/entrabot/efferent_copy.py
Location: L105-L107, L154-L155, L201-L219
Category: race
Priority: medium
Description
_wrap_result returns the tool's result dict by reference; fire_observe schedules N concurrent _fire_one tasks all sharing the same payload_result/args dicts. A misbehaving sink's call_tool can mutate those dicts while FastMCP is still serializing the body's response to the original caller, breaking the byte-for-byte-unchanged guarantee non-deterministically.
Suggested fix
copy.deepcopy(args_dict) and copy.deepcopy(payload_result) once inside fire_observe before scheduling per-sink tasks, so each sink and the body's return path see independent object graphs.
Filed automatically by a thorough code-review pass over src/entrabot/ on 2026-06-13. Internal review id: #14.
Contributor guide
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Research direction
Read src/entrabot/efferent_copy.py at L105-L107, L154-L155, and L201-L219, starting with _wrap_result and fire_observe. Trace how payload_result and args_dict reach _fire_one and the body's return path. Done means each sink receives independent object graphs and the original tool result remains byte-for-byte unchanged.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- python
- Domain
- backend
- Issue type
- Bug
- Difficulty
- 2/5
- Estimated time
- 1-3 hours
- Activity status
- Quiet
- Clarity
- Clearly specified
- Newbie friendliness
- 78/100