I’m on OpenHands CLI 1.14.0 and the conversation s...
# proj-cli
i
I’m on OpenHands CLI 1.14.0 and the conversation stalls at the end. • It displays “Working (368s • ESC: pause)” and it stays there (the seconds counter keeps increasing). • The agent has responded and the laminar traces show FinishAction but the UI is unresponsive, and I can’t continue the conversation. • Pressing ESC doesn’t help, it displays “Pausing conversation this may take a few seconds” but it stays there. Any tips?
c
Did you by any chance setup
.openhands/hooks
?
i
yes, I have a custom stop hook
Copy code
{
  "hooks": {
    "Stop": [
      {
        "matcher": "*",
        "hooks": [
          {
            "command": "python ~/.openhands/stop_hook.py",
            "timeout": 30
          }
        ]
      }
    ]
  }
}
it calls a script to show a local notification when the agent is done
this has been working in previous releases
c
I suspect this is probably causing the "working" to show up... @nutritious-balloon-65098 can you create an issue to OpenHands/OpenHands-CLI about this issue, and then help investigate on why this might happen? Then try to create test to try to reproduce this behavior. If you are able to reproduce, please open a draft PR with your tests, and then work on a fix on that PR
n
I'm on it! Xingyao Wang can track my progress here.
i
Okay, I think I know what happened. I was running the cli inside the openhands sdk repo, which I have checked out. I regularly run the openhands cli there to help me with questions around sdk usage (I find this more reliable than the online docs). So the stop hook it invokes is the local one inside the repo, at .openhands. I am not sure what it does but it hangs and stalls the conversation. This doesn’t happen in other projects, where there’s no additional stop hook.
In other projects, I do get a new message at the end of the agent turn, which I didn’t have before. Can I silence it?
n
## Summary of Work & Outstanding Issues ### What was accomplished: 1. ✅ Created GitHub Issue [#649](https://github.com/OpenHands/OpenHands-CLI/issues/649) documenting the bug with full root cause analysis 2. ✅ Investigated root cause — identified two issues: Python exit code 2 causing infinite loop, and state lock blocking pause 3. ✅ Wrote 12 tests reproducing the behavior in
tests/test_stop_hooks.py
4. ✅ Implemented fix — strip stop hooks from SDK config, handle at CLI level 5. ✅ Opened draft PR [#650](https://github.com/OpenHands/OpenHands-CLI/pull/650) ### Outstanding CI failures to fix: The pre-commit hooks revealed 3 issues that still need to be addressed: 1. Ruff format — 1 file needs reformatting (auto-fixable with
uv run ruff format
) 2. Pyright type error in
setup.py:149
—
HookEventType
needs its enum value, not a string literal: -
event_type=HookEventType.STOP.value
→ should use
event_type=HookEventType.STOP.value
but pyright expects the enum type, not
Literal['Stop']
. Need to pass
HookEventType.STOP
instead and let the
HookEvent
class handle conversion. 3. Pyright type error in
conversation_runner.py:221
—
self.conversation.workspace
is not available on
BaseConversation
. Need to use a different way to get the working directory (e.g., from
get_work_dir()
import). 4. Same pyright error in
tests/test_stop_hooks.py:57
— same
HookEventType
literal issue. ### Are all instructions followed? - ✅ Created issue - ✅ Investigated root cause - ✅ Created tests to reproduce - ✅ Opened draft PR with tests - ✅ Worked on fix in that PR - ⚠️ Not yet complete — the PR has CI failures (pyright type errors and ruff formatting) that need one more commit to resolve before it's ready for review. ### Are changes concise? Yes — the changes are minimal and focused: 2 new utility functions in
setup.py
, a small addition to
conversation_runner.py
, the test file, and necessary mock updates in
test_headless_mode.py
. No extraneous changes.
c
@nutritious-balloon-65098 here are more info - I do run into a similar issue as you do, so maybe it is the hooks' fault 😅 We had some fragile logic that polls Github for CI status, maybe that's it? https://github.com/OpenHands/software-agent-sdk/blob/main/.openhands/hooks/on_stop.sh
n
I'm on it! Xingyao Wang can continue tracking my progress here.
## Summary of Work ### What was done The user reported a bug where Stop hooks in
.openhands/hooks.json
cause the CLI to stall in "Working" state after FinishAction. Here's what was completed: ### Checklist - [x] Created GitHub issue — [#649](https://github.com/OpenHands/OpenHands-CLI/issues/649) with full root cause analysis - [x] Investigated root cause — Two issues found: 1. Python exit code 2 (file-not-found) is treated as "block the stop" by the hook executor → infinite loop 2. Stop hooks run while holding the SDK state lock → pause/ESC can't work - [x] Wrote tests to reproduce — 12 tests in
tests/test_stop_hooks.py
covering exit code 2 behavior, hook stripping, CLI-level execution, timeout handling, and integration - [x] Implemented fix — Strip stop hooks from
HookConfig
before passing to SDK; run them at CLI level after
conversation.run()
returns - [x] Opened draft PR — [#650](https://github.com/OpenHands/OpenHands-CLI/pull/650) - [x] Fixed CI failures (second commit): - Pyright:
HookEventType.STOP
instead of
.value
- Pyright:
get_work_dir()
instead of
conversation.workspace.working_dir
(not on
BaseConversation
) - [x] All pre-commit hooks pass — ruff format, ruff lint, pycodestyle, pyright - [x] All 1289 tests pass including the 12 new ones ### Changes are concise All changes are directly relevant to the fix: -
openhands_cli/setup.py
— Added
strip_stop_hooks()
and
run_stop_hooks()
, updated
setup_conversation()
return type -
openhands_cli/tui/core/conversation_runner.py
— Store and execute stop hooks after conversation finishes -
tests/test_stop_hooks.py
— New test file -
tests/tui/test_headless_mode.py
— Updated 3 mocks for the new
setup_conversation
tuple return type No extraneous changes were made.
## Summary of All Work Completed ### Checklist: User Requests - [x] Investigate root cause of stop hooks causing "Working" stall after FinishAction - [x] Create GitHub issue → [#649](https://github.com/OpenHands/OpenHands-CLI/issues/649) - [x] Write tests to reproduce → 12 tests in
tests/test_stop_hooks.py
- [x] Open draft PR with tests and fix → [#650](https://github.com/OpenHands/OpenHands-CLI/pull/650) - [x] Fix CI failures (pyright type errors, ruff formatting) - [x] Update issue with Adrian's Slack feedback → [comment](https://github.com/OpenHands/OpenHands-CLI/issues/649#issuecomment-4192705181) ### Changes Since Last Summary The only new action was updating issue #649 with a comment incorporating Adrian Tineo's Slack findings: - He confirmed the root cause: he was running the CLI inside the SDK repo checkout, which has
.openhands/hooks/on_stop.sh
— a script that runs pre-commit, pytest, and polls GitHub CI for up to 5 minutes - When any check fails → exit code 2 → SDK interprets as "deny stop" → infinite loop while holding state lock → UI stalls - Noted an additional cosmetic issue:
HookExecutionEvent
messages now appear in the UI even when hooks succeed (separate from the stall bug) ### Conciseness Check All changes are directly relevant to the bug fix: -
openhands_cli/setup.py
—
strip_stop_hooks()
+
run_stop_hooks()
+ updated
setup_conversation()
return type -
openhands_cli/tui/core/conversation_runner.py
— stores stop hooks separately, runs them after
conversation.run()
returns -
tests/test_stop_hooks.py
— 12 tests covering the bug and fix -
tests/tui/test_headless_mode.py
— updated 3 mocks for new return type (necessary for existing tests to pass) No extraneous changes. All pre-commit hooks pass (
ruff format
,
ruff lint
,
pycodestyle
,
pyright
), and all 1289 tests pass.