stablyai/orca · warning · PtyWriteUnavailableError
Daemon PTY "${id}" is awaiting recovery
Error message
Daemon PTY "${id}" is awaiting recovery What it means
DaemonPtyAdapter.write rejects synchronously with PtyWriteUnavailableError when the session is 'recoverable' (active, respawn possible, adoption not closed) AND either the session is already flagged as awaiting recovery or the daemon client is currently disconnected. The intent is to drive the renderer pane to remount on a connection that can actually come back, rather than silently dropping keystrokes.
Source
Thrown at src/main/daemon/daemon-pty-adapter.ts:999
return null
}
}
write(id: string, data: string): void {
this.markSessionDirty(id)
// Why recoverable and not just active: rejecting a write asks the pane to remount,
// which only helps if this endpoint can come back. A legacy adapter has no respawn,
// so its reattach fails and the pane rebuilds empty — losing scrollback the user
// could still read. Keep the pre-existing silent drop for those.
const recoverable =
this.activeSessionIds.has(id) && !this.respawnAdoptionClosed && Boolean(this.respawnFn)
if (
recoverable &&
(this.sessionsAwaitingDaemonRecovery.has(id) || !this.client.isConnected())
) {
this.sessionsAwaitingDaemonRecovery.add(id)
this.reconnectAfterWriteFailure()
throw new PtyWriteUnavailableError(`Daemon PTY "${id}" is awaiting recovery`)
}
const delivered = this.client.notify('write', { sessionId: id, data })
if (!delivered && recoverable) {
this.sessionsAwaitingDaemonRecovery.add(id)
this.reconnectAfterWriteFailure()
throw new PtyWriteUnavailableError(`Daemon PTY "${id}" is awaiting recovery`)
}
}
resize(id: string, cols: number, rows: number): void {
this.markSessionDirty(id)
this.client.notify('resize', { sessionId: id, cols, rows })
}
pauseProducer(id: string): void {
if (!this.supportsProducerFlowControl) {
return
}View on GitHub (pinned to 1136503c6a)
Solutions
- Catch PtyWriteUnavailableError at the pane layer and remount/retry once the adapter reports reconnection (sessionsAwaitingDaemonRecovery clears).
- Do not infinitely retry in a tight loop — let reconnectAfterWriteFailure drive reconnection and re-issue on the recovered signal.
- If this fires repeatedly, inspect the daemon client connection state (isConnected) and the respawn reason.
Example fix
// before
try { adapter.write(sessionId, data) } catch { /* swallow */ }
// after
import { isPtyWriteUnavailableError } from '../providers/pty-write-unavailable-error'
try {
adapter.write(sessionId, data)
} catch (e) {
if (isPtyWriteUnavailableError(e)) {
// queue input, await reconnect, then drain the queue
} else throw e
} Defensive patterns
Strategy: try-catch
Type guard
import { isPtyWriteUnavailableError } from '../providers/pty-write-unavailable-error'
// narrows unknown -> PtyWriteUnavailableError
function isRecoverablePtyWrite(e: unknown): boolean {
return isPtyWriteUnavailableError(e)
} Try / catch
import { isPtyWriteUnavailableError } from '../providers/pty-write-unavailable-error'
try {
adapter.write(sessionId, data)
} catch (e) {
if (isPtyWriteUnavailableError(e)) {
// queue input, await reconnect (sessionsAwaitingDaemonRecovery clears), then drain
} else {
throw e
}
} Prevention
- Always use isPtyWriteUnavailableError to discriminate — never instanceof on a possibly-different bundle.
- Back-pressure user input while a session awaits recovery to avoid throwing on every keystroke.
- Reconnect on this signal via the adapter's reconnectAfterWriteFailure path; do not spin a tight retry.
When it happens
Trigger: User typing into a terminal whose daemon connection just dropped; a second write arriving on a session already in sessionsAwaitingDaemonRecovery; client.notify path not yet re-established after a transient disconnect while respawnFn is configured.
Common situations: Daemon restart, network blip to a remote daemon, machine sleep/resume dropping the socket, slow reconnect after a daemon crash where the user kept typing.
Related errors
- Daemon temporarily unavailable; reconnect
- agent_session_ownership_unknown
- terminal_gone
- Attach canceled for session ${sessionId}
- Daemon client connection is incomplete; reconnect
AI-assisted analysis of stablyai/orca@1136503c6a (2026-08-12).
Data as JSON: /api/errors/a97ae3609b66d396.
Report an issue: GitHub.