Skip to content

fix(cancel): always call abort_session - #433

Merged
sudo-tee merged 1 commit into
sudo-tee:mainfrom
phanen:fix/cancel
Jun 28, 2026
Merged

fix(cancel): always call abort_session#433
sudo-tee merged 1 commit into
sudo-tee:mainfrom
phanen:fix/cancel

Conversation

@phanen

@phanen phanen commented Jun 28, 2026

Copy link
Copy Markdown
Contributor

Problem:
M.cancel was gated on state.active_session and state.jobs.is_running(). state.jobs.is_running() is true only while
the client has an in-flight HTTP request; once the request returns, the
counter is back to zero. So attaching to a session whose model is
already processing, or toggling off/on with persist_state, leaves
cancel with nothing to do.

The counter that drives the 3-strike server restart must keep gating on
state.jobs.is_running() — its purpose is to detect the user is trying
to abort an in-flight request and the server is not responding, not to
count cancel attempts on an idle session.

Solution:
Move the state.jobs.is_running() gate to wrap only the counter
increment. The cancel itself always runs. abort_session is a no-op on
the server for an idle session, so calling it is harmless.

Problem:
`M.cancel` was gated on `state.active_session and
state.jobs.is_running()`. `state.jobs.is_running()` is true only while
the client has an in-flight HTTP request; once the request returns, the
counter is back to zero. So attaching to a session whose model is
already processing, or toggling off/on with `persist_state`, leaves
cancel with nothing to do.

The counter that drives the 3-strike server restart must keep gating on
`state.jobs.is_running()` — its purpose is to detect the user is trying
to abort an in-flight request and the server is not responding, not to
count cancel attempts on an idle session.

Solution:
Move the `state.jobs.is_running()` gate to wrap only the counter
increment. The cancel itself always runs. `abort_session` is a no-op on
the server for an idle session, so calling it is harmless.

Tests:
- `aborts running session even when ui is not visible` (existing)
  covers the in-flight path.
- `aborts when the model is processing on the server but no client
  request is in flight` reproduces the bug and asserts abort is
  called even with no in-flight request.
- `does not count cancel toward the server-restart threshold when
  no client request is in flight` confirms the counter gate is
  preserved, so a stuck-idle path does not trigger a spurious
  server restart.
@phanen

phanen commented Jun 28, 2026

Copy link
Copy Markdown
Contributor Author

The counter that drives the 3-strike server restart must keep gating on
state.jobs.is_running() — its purpose is to detect the user is trying
to abort an in-flight request and the server is not responding

llm analysis from git blame. Not sure if this is the designed purpose.

@sudo-tee

Copy link
Copy Markdown
Owner

This was actually a real issue. The fix is right. No need to gate check. The abort intent is usually something you want to happen immediately.

Thanks for the fix

@sudo-tee
sudo-tee merged commit a677af6 into sudo-tee:main Jun 28, 2026
5 checks passed
@phanen
phanen deleted the fix/cancel branch June 30, 2026 03:47
disrupted pushed a commit to disrupted/opencode-native.nvim that referenced this pull request Jul 23, 2026
Problem:
`M.cancel` was gated on `state.active_session and
state.jobs.is_running()`. `state.jobs.is_running()` is true only while
the client has an in-flight HTTP request; once the request returns, the
counter is back to zero. So attaching to a session whose model is
already processing, or toggling off/on with `persist_state`, leaves
cancel with nothing to do.

The counter that drives the 3-strike server restart must keep gating on
`state.jobs.is_running()` — its purpose is to detect the user is trying
to abort an in-flight request and the server is not responding, not to
count cancel attempts on an idle session.

Solution:
Move the `state.jobs.is_running()` gate to wrap only the counter
increment. The cancel itself always runs. `abort_session` is a no-op on
the server for an idle session, so calling it is harmless.

Tests:
- `aborts running session even when ui is not visible` (existing)
  covers the in-flight path.
- `aborts when the model is processing on the server but no client
  request is in flight` reproduces the bug and asserts abort is
  called even with no in-flight request.
- `does not count cancel toward the server-restart threshold when
  no client request is in flight` confirms the counter gate is
  preserved, so a stuck-idle path does not trigger a spurious
  server restart.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants