stablyai/orca · error · Error
PTY provider unavailable for worktree deletion: ${worktreeId
Error message
PTY provider unavailable for worktree deletion: ${worktreeId} What it means
During destructive worktree removal, Orca resolves the PTY provider to stop all running processes for the worktree before deleting it. For a remote (SSH) host it calls getSshPtyProvider(connectionId); for local it calls getLocalPtyProvider(). If the resolved provider is undefined, it cannot kill the worktree's terminals and refuses to proceed with a destructive delete, naming the worktreeId in the message. This is a safety gate: deleting without stopping PTYs would orphan processes.
Source
Thrown at src/main/ipc/worktrees.ts:171
worktreeId: string
hostId?: ExecutionHostId
force?: boolean
/** Explicit Force Delete only — `force` alone is set by the ordinary confirmation (#11960). */
allowUnverifiedPtyStop?: boolean
skipArchive?: boolean
}
type DetectedWorktreeRequestArgs = { repoId: string } | ListDetectedWorktreesArgs
async function stopPtysForDestructiveWorktreeRemoval(
runtime: OrcaRuntimeService,
worktreeId: string,
options: { connectionId?: string; allowUnverifiedStop?: boolean } = {}
): Promise<void> {
const { connectionId, allowUnverifiedStop } = options
const provider = connectionId ? getSshPtyProvider(connectionId) : getLocalPtyProvider()
if (!provider) {
throw new Error(`PTY provider unavailable for worktree deletion: ${worktreeId}`)
}
const teardownResult = await killAllProcessesForWorktree(worktreeId, {
runtime,
// Why: `repoId::path` ids repeat across hosts, so an unfenced sweep stops a same-id
// workspace's terminals on another connection — and the selector lookup this replaces
// throws `selector_ambiguous` the moment two hosts own the id.
resolvedWorktreeId: worktreeId,
...(connectionId ? { resolvedConnectionId: connectionId } : {}),
localProvider: provider,
onPtyStopped: clearProviderPtyState,
requirePhysicalStop: true,
// Why (#11960): set only by an explicit Force Delete, never by the ordinary
// confirmation — otherwise the gate would be off on the primary delete path.
...(allowUnverifiedStop ? { allowUnverifiedStop: true } : {}),
...(connectionId ? { includeLocalRegistry: false } : {})
})
const total =
teardownResult.runtimeStopped + teardownResult.providerStopped + teardownResult.registryStoppedView on GitHub (pinned to 1136503c6a)
Solutions
- For SSH deletes: reconnect the host so the SSH PTY provider is registered, then retry the delete.
- For local deletes: ensure the local PTY subsystem has initialized (restart Orca if it failed to boot).
- If the worktree truly has no running processes and the connection is gone, use Force Delete with allowUnverifiedStop so the gate is bypassed (the provider check still requires a provider, so reconnect first).
- Verify the connectionId passed to the delete matches a currently-registered connection.
Example fix
// before
const provider = connectionId ? getSshPtyProvider(connectionId) : getLocalPtyProvider()
if (!provider) {
throw new Error(`PTY provider unavailable for worktree deletion: ${worktreeId}`)
}
// after — distinguish local vs ssh and hint the recovery
if (!provider) {
const where = connectionId ? `SSH connection ${connectionId}` : 'local PTY subsystem'
throw new Error(`Cannot delete ${worktreeId}: no PTY provider for ${where}. Reconnect the host (SSH) or restart Orca (local) and retry.`)
} Defensive patterns
Strategy: validation
Validate before calling
// Before delete: ensure a PTY provider is available
const provider = connectionId ? getSshPtyProvider(connectionId) : getLocalPtyProvider()
if (!provider) {
if (connectionId) await reconnectSsh(connectionId)
const retry = connectionId ? getSshPtyProvider(connectionId) : getLocalPtyProvider()
if (!retry) return { ok: false, error: `No PTY provider for ${worktreeId}. Reconnect host or restart Orca.` }
} Type guard
function isPtyProvider(provider: unknown): provider is PtyProvider {
return !!provider && typeof (provider as any).stop === 'function'
} Try / catch
catch (err) {
if (err instanceof Error && err.message.startsWith('PTY provider unavailable for worktree deletion')) {
if (connectionId) await reconnectSsh(connectionId)
return retryDelete()
}
throw err
} Prevention
- Reconnect SSH hosts before deleting remote worktrees so the SSH PTY provider is registered.
- Ensure the local PTY subsystem initialized at startup (restart Orca if it didn't).
- Verify the connectionId passed to delete matches a currently registered connection.
- Use Force Delete only after confirming no live processes, and only after a provider is available.
When it happens
Trigger: A worktree delete (or Force Delete) calling stopPtysForDestructiveWorktreeRemoval where connectionId is set but getSshPtyProvider returns undefined, or connectionId is absent and getLocalPtyProvider returns undefined. Reached at worktrees.ts:171.
Common situations: SSH connection dropped before the delete ran (no SSH PTY provider registered for that connectionId); local PTY subsystem not initialized yet at startup; connectionId stale after a reconnect that didn't re-register the provider; provider unregistered by a teardown racing the delete.
Related errors
- advertised-url-watcher.ts no longer contains \`${marker}\`
- ORCA_PTY_BENCH_PTY_COUNT must be positive, received ${PTY_CO
- ORCA_PTY_BENCH_PAYLOAD_CHARS must be positive, received ${PA
- ORCA_PTY_BENCH_RUNS must be positive, received ${RUNS}
- ORCA_PTY_BENCH_INGRESS_CHUNKS must be positive, received ${I
AI-assisted analysis of stablyai/orca@1136503c6a (2026-08-12).
Data as JSON: /api/errors/2d6463737240ef0b.
Report an issue: GitHub.