You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
fix(hub): throw when restarting a session with a closed stream
restart() silently returned once a startChildProcess()/startPtySession()
session's streamClosed flag was set — after a natural process exit or
terminate(). That flag guards a single-use ReadableStream controller
which cannot be reopened, so restarting in place genuinely cannot
work; the defect was that a caller had no way to distinguish success
from a no-op (hub:terminals:restart resolves either way).
Throw a new DF8206 diagnostic instead, pointing callers at
remove(session) + a fresh start*() with a new id. This is a behaviour
change on a case #148 (four days ago) deliberately pinned as a silent
no-op — the two host-terminals tests that pinned it are updated to
assert the rejection while keeping their original assertions (stream
stays closed / status stays 'stopped'): only the silence changes.
Not reusing DF8205 (its fix text describes restartable: false, which
would misdescribe a spent stream) and not flipping `restartable` in
closeStream() (a different concept — "lifecycle owned elsewhere" vs.
"stream spent").
🤖 Generated with [Claude Code](https://claude.com/claude-code)
# DF8206: Terminal Session Restart on Closed Stream
6
+
7
+
## Message
8
+
9
+
> Terminal session "`{id}`" cannot be restarted — its output stream is already closed
10
+
11
+
## Cause
12
+
13
+
`restart()` was called on a `startChildProcess()` or `startPtySession()` session whose output stream is already closed. The stream closes irreversibly on a natural process exit or after `terminate()` — it backs a single-use `ReadableStream` controller that cannot be reopened, so restarting in place is not possible once it has closed.
14
+
15
+
## Fix
16
+
17
+
`ctx.terminals.remove(session)` the spent session, then spawn a fresh one via `startChildProcess()` / `startPtySession()` with a new id.
18
+
19
+
## Source
20
+
21
+
-[`packages/hub/src/node/host-terminals.ts`](https://github.com/devframes/devframe/blob/main/packages/hub/src/node/host-terminals.ts) — the `restart()` handle returned by `startChildProcess()` and `startPtySession()` throws this once the session's stream has closed.
why: (p: {id: string})=>`Terminal session "${p.id}" is not restartable`,
68
68
fix: 'It was registered with `restartable: false`; restart it through its owner\'s controls, or spawn it with `restartable: true` (the default) to allow in-place restarts.',
69
69
},
70
+
DF8206: {
71
+
why: (p: {id: string})=>`Terminal session "${p.id}" cannot be restarted — its output stream is already closed`,
72
+
fix: 'The session already exited (or was terminated) and its stream is spent. `ctx.terminals.remove(session)` then re-`startChildProcess()`/`startPtySession()` with a fresh id instead.',
73
+
},
70
74
DF8400: {
71
75
why: (p: {id: string})=>`Command "${p.id}" is already registered`,
/** Throws `DF8206` once the session's output stream has closed (after a natural exit or `terminate()`) — `remove()` it and start a fresh session instead. */
/** Current foreground process name, when the backend can resolve it. */
140
141
getProcessName: ()=>string|undefined
141
142
terminate: ()=>Promise<void>
143
+
/** Throws `DF8206` once the session's output stream has closed (after a natural exit or `terminate()`) — `remove()` it and start a fresh session instead. */
0 commit comments