fix(sdk): reject unknown event parents on append#4089
Open
hxaxd wants to merge 1 commit into
Open
Conversation
Contributor
There was a problem hiding this comment.
Pull request overview
This PR hardens the SDK’s persistent EventLog against malformed/cyclic event graphs by validating explicit parent_id references at append-time, preventing forward/self references that could otherwise surface later as load-time failures.
Changes:
- Add
EventLog.append()validation to reject explicitparent_idvalues that are neitherNone,ROOT_PARENT_ID, nor an already-present event ID. - Update/extend event-tree tests to (a) simulate an already-corrupted persisted cycle and (b) assert append-time rejection/acceptance of explicit parent IDs.
Reviewed changes
Copilot reviewed 2 out of 2 changed files in this pull request and generated no comments.
| File | Description |
|---|---|
tests/sdk/conversation/test_event_tree.py |
Adds coverage for append-time parent validation and adjusts the cycle test to simulate corruption that bypasses append-time checks. |
openhands-sdk/openhands/sdk/conversation/event_store.py |
Enforces that an explicit non-root parent_id must already exist in the log before writing the event, preventing forward/self references. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
HUMAN:
This PR was directed by me and implemented with AI assistance. I control the overall architecture and functional logic, have fully reviewed all changes and relevant test results, and take full responsibility for all modifications in this PR.
AGENT:
Why
A cyclic event graph prevents a conversation from loading:
ConversationState.create()→rebuild_view()→path_to_root()→ValueErrorNormally,
_stamp_parent_id()assigns the current leaf as the parent, so the referenced event already exists. Forks also copy events in parent-first order.The invalid case can occur when patched code or a custom agent emits an event with an explicit
parent_id._stamp_parent_id()preserves non-null values, andEventLog.append()previously wrote them without checking whether the parent existed. This allowed a forward reference such asA → B, followed byB → A, creating a cycle that was only detected during the next load.Summary
EventLog.append()after synchronizing the on-disk index.None,ROOT_PARENT_ID, or an event ID already present in the log.Because the log is append-only, requiring an ordinary parent to already exist prevents new cycles without changing legacy events, explicit roots, forks, or navigation.
Issue Number
Fixes OpenHands/OpenHands#15247
How to Test
Ran the event-store and event-tree unit tests:
Result:
Also tested the real
EventLogwrite path without mocks:Pre-commit checks passed, including Ruff, pycodestyle, Pyright, and import dependency checks.
Video/Screenshots
N/A — SDK event-log validation with no UI changes.
Type