has anyone ever seen a situation where OpenHands C...
# questions
m
has anyone ever seen a situation where OpenHands CLI stops processing after running successfully for many turns, and then won't respond to new prompts? I have found that in cases like this if I remove
~/.openhands/conversations/XXXXX/base_state.json
and then re-start openhands, it will be able to resume where it left off. currently running main 2ba5350 (1.13.0)
n
Yep, I've seen this it's an agent-sdk bug..the StuckDetector sets
execution_status="stuck"
which gets auto-persisted to
base_state.json
. On restart that status is restored as-is, but send_message() only resets
FINISHED→IDLE
, not
STUCK
so run() sees "stuck" and immediately exits without processing and deleting
base_state.json
works because it forces a fresh
IDLE
state while keeping your events intact. Fix should go in
agent-sdk
ConversationState.create()
needs to reset terminal statuses on resume.
🙌 1
m
wow, thanks for letting me know and giving me the details. I was worried I was doing something wrong. do you know if there is an existing issue to track this? should we open one?
n
Not aware of an existing issue worth opening one on agent-sdk @calm-artist-7206 @chilly-france-44439 @limited-student-10747 is there already a tracking issue for this?
👍 1
c
No, I don't think there is. @nutritious-balloon-65098 Verify this and open a new issue if there isn't one
Actually I remember one about how to behave after stuck, let's see if OH finds it... not sure on what repo it was though 😅
👍 1
m
@calm-artist-7206 in a situation like this do we ask OpenHands here to try again? I'm not sure what the protocol for interacting with this instance is..
c
I've run into the issue of agent stuck in another project 😅 Hopefully this project will fix the
execution_status="stuck"
issue here https://github.com/OpenHands/software-agent-sdk/pull/2384
❤️ 3
m
wow! it's in main now?! I'm going to try it out. thank you very much for tackling this @chilly-france-44439
🙌 1
c
LMK if it is still not working for you and we can open a new issue 🙂
m
I am still hitting this issue @chilly-france-44439 -- how can I help confirm what the underlying cause is? my base_state.json has some sensitive stuff in it, but I can look for excerpts if it would help you
@nutritious-balloon-65098 can you see a reason why I would still have session stalling behavior even after this fix? https://github.com/OpenHands/software-agent-sdk/pull/2384
n
I'm on it! Buttetsu can track my progress here.
## Summary I analyzed why session stalling might still occur after PR #2384 by examining the fix and the relevant codebase. What PR #2384 Fixed: 1. JSON control characters in tool_call.arguments (some models emit literal
\n
,
\t
instead of JSON escapes) 2. Stale EventLog index recovery when
_path(i)
raises KeyError 3. STUCK status recovery - added STUCK to states that reset to IDLE in
send_message()
and transition to RUNNING in
run()
Potential Remaining Causes for Stalling: 1. Race condition window - After
agent.step()
completes, stuck detection runs and may persist STUCK status to
base_state.json
before the loop checks for it, creating a timing issue 2. ConversationState.create() doesn't reset terminal states - When resuming, persisted
execution_status
loads directly without resetting to IDLE; relies on send_message()/run() to do this 3. RemoteConversation - If using agent-server, LocalConversation fixes don't apply 4. base_state.json corruption - Could contain invalid data beyond execution_status To diagnose further, check the execution_status in your base_state.json:
Copy code
bash
cat ~/.openhands/conversations/XXXXX/base_state.json | jq '.execution_status'
If you'd like me to investigate further, please share what the execution_status value shows and whether you're using LocalConversation or RemoteConversation.
m
@nutritious-balloon-65098 here are my results. Also, I think I am using LocalConveration? I am running against a local model at least if that helps. How can I confirm?
Copy code
$ cat base_state.json | jq '.execution_status'
"stuck"
n
## Summary I identified and fixed the root cause of why session stalling persisted even after PR #2384. Root Cause: PR #2384 fixed
send_message()
and
run()
to reset STUCK→IDLE, but it didn't fix
ConversationState.create()
- the resume path. When resuming a conversation from disk, the persisted
execution_status: "stuck"
was loaded directly without being reset to IDLE. Fix Applied: Added terminal state reset in
ConversationState.create()
at line 339-347 in `openhands-sdk/openhands/sdk/conversation/state.py`: - When resuming a conversation, STUCK, ERROR, and FINISHED statuses are now automatically reset to IDLE - This ensures conversations can recover immediately on resume without requiring
send_message()
or
run()
to be called first Verification: - Pre-commit hooks pass - All stuck-related tests pass - Manual test confirms STUCK→IDLE on resume works correctly Would you like me to commit this fix and create a PR?
## Summary Issue Identified: Session stalling persisted even after PR #2384 because the fix only addressed
send_message()
and
run()
methods, but not the resume path in
ConversationState.create()
. Root Cause: When resuming a conversation from disk, the persisted
execution_status
(STUCK, ERROR, FINISHED) was loaded directly without resetting to IDLE. This caused sessions to remain stuck unless
send_message()
or
run()
was explicitly called first. Fix Applied: Added terminal status reset in
ConversationState.create()
at line 339-347 in `openhands-sdk/openhands/sdk/conversation/state.py`: - Reset
FINISHED
,
ERROR
, and
STUCK
statuses to
IDLE
on resume - This ensures conversations can recover immediately upon resume without requiring additional method calls Verification: - Pre-commit hooks pass ✅ - All stuck-related tests pass ✅ - Manual test confirms STUCK→IDLE on resume ✅ Git Status: The fix is committed locally to branch
fix/reset-terminal-status-on-resume
. However, I cannot push to the repository due to insufficient permissions (token only has pull access). The user will need to either test locally or manually create the PR using the provided diff.
c
@magnificent-tiger-32598 do you mind pushing the result to a fork of the repo and submit a PR? I'd be happy to help review it & get it merged
👍 1
m
@nutritious-balloon-65098 even with the fixes your proposed in https://github.com/OpenHands/software-agent-sdk/pull/2466, I am still getting sessions that hang eventually. According to the code review in that PR, the fix may not be the right approach. I can confirm the hung state with
Copy code
$ cat base_state.json | jq '.execution_status'
"stuck"
can you do a deeper investigation into this issue and present an alternative solution please
n
I'm on it! Buttetsu can track my progress here.
## Summary I investigated the session stalling issue that persists even after PR #2466 and found an alternative, more targeted fix. ### Root Cause Identified The bug was in
local_conversation.py
- there were two conflicting checks for STUCK status: 1. Outside the while loop (lines 586-592): Correctly resets STUCK → RUNNING 2. Inside the while loop (lines 602-606): Incorrectly checks for STUCK and breaks immediately This caused the run loop to break immediately after resetting STUCK → RUNNING, leaving the status unchanged and persisted as STUCK. ### Fix Applied Removed STUCK from the pause check inside the while loop - it should only check for PAUSED:
Copy code
diff
- if self._state.execution_status in [
-     ConversationExecutionStatus.PAUSED,
-     ConversationExecutionStatus.STUCK,
- ]:
+ if (
+     self._state.execution_status
+     == ConversationExecutionStatus.PAUSED
+ ):
### Verification - All 112 tests in
tests/sdk/conversation/local/
pass ✓ - All 9 agent status transition tests pass ✓ - Pre-commit hooks pass ✓ ### Git Status - Branch:
openhands-workspace-2Jq9bpu4zkVejXe0dpLmhl
- Modified file:
openhands-sdk/openhands/sdk/conversation/impl/local_conversation.py
The fix is cleaner than PR #2466 because it addresses the actual bug in the run loop rather than working around it at resume time. Would you like me to commit the changes and create a PR?
## Summary of My Work I investigated the session stalling issue and made a code change, but the fix did not resolve the problem. Here's what I did: ### Changes Made I modified
openhands-sdk/openhands/sdk/conversation/impl/local_conversation.py
at lines 602-606, removing STUCK from the pause check inside the while loop. This was based on my analysis that there was a redundant STUCK check that could cause the session to break immediately after the STUCK→RUNNING reset. ### Test Results - All 112 tests in
tests/sdk/conversation/local/
passed - All 9 tests in
test_agent_status_transition.py
passed - Pre-commit hooks passed ### Outcome The user tested the fix but it did not resolve their issue - the conversation still becomes stuck after many successful steps. ### Next Steps I asked the user to provide debug information from their stuck session to help diagnose the real root cause, including: - The
execution_status
value - Stuck detection configuration - Last events before getting stuck - Any error logs - Agent configuration details The investigation is ongoing pending this debug information.
## Summary of Work ### What I Found I investigated the session stalling issue and identified a bug in
local_conversation.py
where the
run()
method had conflicting logic: 1. Lines 586-592 (outside the while loop): Correctly resets STUCK → RUNNING when starting 2. Lines 602-606 (inside the while loop): Incorrectly checked for STUCK and broke immediately, causing the status to never actually transition to RUNNING ### Fix Applied I made a minimal change to remove STUCK from the pause check inside the while loop:
Copy code
diff
- if self._state.execution_status in [
-     ConversationExecutionStatus.PAUSED,
-     ConversationExecutionStatus.STUCK,
- ]:
+ if (
+     self._state.execution_status
+     == ConversationExecutionStatus.PAUSED
+ ):
### Current Status - Tests pass (112 tests in conversation/local) - Pre-commit passes - However, the user reported the fix didn't work - they still got stuck sessions ### Additional Issue Identified After the user's feedback, I realized there's likely a second issue: after the run loop exits, the status is never reset from STUCK. If the agent completes or the loop breaks for any reason, STUCK persists because there's no cleanup code. ### What I Need From the User To debug further, I asked for: 1. The last event files (event-00700 and event-00701) 2. Any stuck/loop detection logs 3. Whether the agent was actually in a loop or working normally This will help determine if it's a false-positive stuck detection, or if there's another code path causing the issue.
Let me push the changes and provide a final summary:
## Summary I've identified and fixed two bugs in
local_conversation.py
that caused sessions to get permanently stuck: ### Bug 1: Infinite stuck loop (CRITICAL) - Location: Lines 640-645 - Problem: After stuck detection, the code used
continue
which went back to the top of the loop. On the next iteration,
is_stuck()
returned TRUE again (no new events!), creating an infinite loop that never exited. - Fix: Changed
continue
to
break
so the run loop exits cleanly when stuck is detected. ### Bug 2: Resume recovery blocked - Location: Lines 602-606 - Problem: Outside the loop, STUCK → RUNNING was correctly reset. But inside the loop, another check immediately broke if status was STUCK, preventing recovery. - Fix: Removed STUCK from the pause check inside the loop. ### Verification - All 112 tests in
tests/sdk/conversation/local/
pass ✓ - All 9 status transition tests pass ✓ - Pre-commit hooks pass ✓ --- Would you like me to commit the changes and create a PR? The fix is cleaner and more targeted than PR #2466 - it fixes the actual bugs in the run loop rather than working around them at resume time.
## Summary of Work Done I investigated and fixed the session stalling issue in OpenHands CLI where conversations would get stuck and not respond to new messages after resuming. ### Root Cause Multiple bugs in the stuck detection logic in `local_conversation.py`: 1. Infinite loop bug: After stuck detection triggered, the code used
continue
which went back to the top of the loop and triggered stuck detection again (same events), creating an infinite loop 2. Resume recovery blocked: Inside the run loop, there was a check for STUCK status that would immediately break, preventing recovery even though STUCK→RUNNING was reset outside the loop 3. False positive on resume: When sending a new message after getting stuck, the stuck detector would immediately trigger again because the old "stuck pattern" was still in the event history ### Fixes Applied (in
openhands-sdk/openhands/sdk/conversation/impl/local_conversation.py
) 1. Removed STUCK from pause check inside the while loop 2. Changed
continue
to
break
after stuck detection to exit the loop cleanly 3. Added
first_iteration
flag to skip stuck detection on first iteration, giving the agent a chance to process new user messages 4. Added event count tracking to only check for stuck patterns when new events have been added ### Verification - All 112 tests in
tests/sdk/conversation/local/
pass - Pre-commit hooks pass The fixes allow conversations to recover from stuck states when new user messages are sent, without requiring manual deletion of
base_state.json
.
m
@chilly-france-44439 this fix seems to be working! ran it through two long-running sessions now with no issues, it never stopped until actually finished https://github.com/OpenHands/software-agent-sdk/pull/2470
@chilly-france-44439 the new code roast recommendations seem beyond my current scope? it has been working flawlessly for me with those changes, almost 24 hrs running now. I will standby before going any further, sound good?
c
@magnificent-tiger-32598 🙂 Yep i think you can standby and wait for review - thank you for your contribution! @strong-ice-84145, since you've also help implemented this part a while ago, I wonder if you'd have a chance to take a look at the logic in https://github.com/OpenHands/software-agent-sdk/pull/2470 and see if it looks good to you? Would love another pair of eyes besides me since this is relatively high risk area in SDK lolsob
m
thanks @chilly-france-44439! I get the impression from the analysis that the fix isn't elegant.. and I can't explain exactly why it is working.. but I wanted to make sure I let you know that since making these changes things have been rock solid for me
👍 1