Remove StateProxy from flow state access#6327
Conversation
There was a problem hiding this comment.
Summary: This PR removes thread-safe flow state proxy exports/access and exposes the underlying flow state directly.
Risk: Low risk. No exploitable security vulnerabilities were identified because the change affects internal flow state concurrency behavior and does not introduce public endpoints, authentication/authorization changes, SQL/file/network handling, or new trust boundaries.
|
No actionable comments were generated in the recent review. 🎉 ℹ️ Recent review info⚙️ Run configurationConfiguration used: Organization UI Review profile: CHILL Plan: Pro Plus Run ID: 📒 Files selected for processing (8)
💤 Files with no reviewable changes (2)
✅ Files skipped from review due to trivial changes (1)
🚧 Files skipped from review as they are similar to previous changes (2)
📝 WalkthroughWalkthroughThe PR removes state proxy wrappers from the Flow runtime, changes ChangesState proxy removal and direct state access
Suggested reviewers
🚥 Pre-merge checks | ✅ 4 | ❌ 1❌ Failed checks (1 warning)
✅ Passed checks (4 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing Touches📝 Generate docstrings
🧪 Generate unit tests (beta)
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. Comment |
There was a problem hiding this comment.
Cursor Bugbot has reviewed your changes and found 1 potential issue.
❌ Bugbot Autofix is OFF. To automatically fix reported issues with cloud agents, enable autofix in the Cursor dashboard.
Reviewed by Cursor Bugbot for commit f724c73. Configure here.
There was a problem hiding this comment.
Actionable comments posted: 1
🤖 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.
Inline comments:
In `@lib/crewai/tests/test_flow.py`:
- Around line 1513-1518: The test for parallel branch completion is too weak
because it only checks final state and can still pass if the joined listener
runs too early. Tighten the assertions in
test_parallel_branches_complete_before_join and the related verify_state checks
so they explicitly record and compare event order, then assert the joined
listener executes only after both branch updates are present. Use the existing
listener/branch state assertions in this test to add ordering/index checks
rather than relying on membership alone.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: Organization UI
Review profile: CHILL
Plan: Pro Plus
Run ID: 534b1898-3542-41c1-9650-79e98d487e68
📒 Files selected for processing (6)
lib/crewai/src/crewai/experimental/agent_executor.pylib/crewai/src/crewai/flow/flow.pylib/crewai/src/crewai/flow/runtime/__init__.pylib/crewai/tests/agents/test_agent_executor.pylib/crewai/tests/test_flow.pylib/crewai/tests/test_flow_conversation.py
💤 Files with no reviewable changes (1)
- lib/crewai/src/crewai/flow/flow.py
f724c73 to
842f1fc
Compare
`StateProxy` looked like a thread-safety boundary, but it only protected a small slice of state operations. Some examples of operations that were not covered: - `self.state.counter += 1`, `self.state["counter"] += 1` (increments) - `self.state.user.profile.score += 1` (nested object mutations) - `self.state.config["limits"]["max"] = 10` (mutation through model fields) - `self.state.items[0].status = "done"` (list/container mutations) This commit decided to remove it completely for simplicity and performance: - Simpler runtime code - attr read: 24x faster, attr write: 27x faster, list append: 19x faster (local benchmark) - Clearer concurrency contract (lifecycle locks remain, but arbitrary shared state mutation is not presented as thread-safe)
842f1fc to
f0dd16a
Compare

StateProxylooked like a thread-safety boundary, but it only protected a small slice of state operations. Some examples of operations that were not covered:self.state.counter += 1,self.state["counter"] += 1(increments)self.state.user.profile.score += 1(nested object mutations)self.state.config["limits"]["max"] = 10(mutation through model fields)self.state.items[0].status = "done"(list/container mutations)This commit decided to remove it completely for simplicity and performance:
Note
Medium Risk
Parallel flow listeners can race on shared
flow.statemutations where proxies previously gave partial protection; callers must not assume thread-safe arbitrary state updates.Overview
Removes the
StateProxy/LockedDictProxy/LockedListProxylayer andFlow._state_lock.flow.statenow returns the underlying state object directly instead of a thread-safe wrapper.Public API: Those proxy types are dropped from
crewai.flow.flowexports.AgentExecutorno longer exposes a customstateproperty overStateProxy.Tests no longer assert atomic shared-state updates under parallel branches; parallel join behavior is checked via a locked execution-order recorder. Persistence and definition parity tests expect plain state objects (e.g.
isinstance(flow.state, State)instead of_unwrap()).Reviewed by Cursor Bugbot for commit f0dd16a. Bugbot is set up for automated code reviews on this repo. Configure here.
Summary by CodeRabbit
flow.statenow exposes the underlying state object directly.