RunResumeSessionManager: abort with DOMException AbortError, not custom Error - #1036
Merged
Merged
Conversation
kojiwakayama
force-pushed
the
koji/framework-deslop-pass-1
branch
from
April 14, 2026 21:42
eb4e8a5 to
1786e0c
Compare
…lass RunResumeSessionManager.cancelRun aborted the run's signal with `new RunCancelledError()`, the framework's plain `Error` subclass with `name: 'RunCancelledError'`. When provider SDKs (e.g. Anthropic via fetch) saw that as `signal.reason`, their internal background promises rejected with it; if anyone failed to chain a `.catch()` on those, the host process died via unhandledRejection. This is the same bug class that crashed the staging veryfront-agent pods (veryfront-agent#371). The framework version ships into every Veryfront app, so the blast radius here is much bigger. Abort with a DOMException(AbortError) instead — every fetch / stream consumer recognises that as a normal cancellation. Keep RunCancelledError on the waitForSignal reject path so callers can still `instanceof` it; that promise is awaited inline so it's safe. Test pins both: signal.reason is the AbortError shape, and an in-flight waitForSignal still rejects with RunCancelledError. Also bumps to 0.1.203.
kojiwakayama
force-pushed
the
koji/framework-deslop-pass-1
branch
from
April 14, 2026 21:45
1786e0c to
ba14b7f
Compare
kojiwakayama
enabled auto-merge (squash)
April 14, 2026 21:46
4 tasks
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.
Summary
`RunResumeSessionManager.cancelRun` aborted the run's signal with `new RunCancelledError()` — a plain `Error` subclass with `name: 'RunCancelledError'`. When provider SDKs (Anthropic / OpenAI / Google) saw that as `signal.reason`, their internal background promises rejected with it; any one of those that wasn't `.catch`-ed crashed the host process via `unhandledRejection`.
This is the same bug class that crashed staging veryfront-agent pods (fixed in veryfront-agent#371). The framework version ships into every Veryfront app, so the blast radius here is much bigger.
Fix
Abort with a `DOMException('Run cancelled', 'AbortError')` so every fetch/stream consumer recognises it as cancellation. Keep `RunCancelledError` on the `waitForSignal` reject path so callers can still `instanceof` it — that promise is awaited inline, so it's safe.
Tests (red→green TDD)
Follow-up flagged
`src/react/compat/ssr-adapter/stream-renderer.ts:50` has the same shape: `controller.abort(new Error('SSR timeout: ...'))`. Lower impact (the local `onError` falls through harmlessly) but still wrong — the abort-vs-error distinction never matches in the local handler. Out of scope for this PR; happy to do a follow-up.
Test plan