stablyai/orca · warning
SSH provider wait aborted for target "${targetId}".
Error message
SSH provider wait aborted for target "${targetId}". What it means
Thrown by waitForRuntimeSshProviders when the caller-supplied AbortSignal becomes aborted during the up-to-10s polling loop that waits for both the SSH git provider and SSH filesystem provider to register for a freshly connected target. The connect attempt in connectRuntimeOwnedSshTarget is being cancelled mid-flight, so the runtime-owned SSH target is removed (cleanup) and the abort error is rethrown. It is a cooperative cancellation signal, not a transport failure.
Source
Thrown at src/main/ephemeral-vm-runtime-ssh.ts:63
export async function disconnectRuntimeOwnedSshTarget(targetId: string | undefined): Promise<void> {
if (!targetId) {
return
}
await disconnectRegisteredSshTarget(targetId)
}
export async function removeRuntimeOwnedSshTarget(targetId: string | undefined): Promise<void> {
if (!targetId) {
return
}
await removeRegisteredSshTarget(targetId)
}
async function waitForRuntimeSshProviders(targetId: string, signal?: AbortSignal): Promise<void> {
const startedAt = Date.now()
while (Date.now() - startedAt < SSH_PROVIDER_READY_TIMEOUT_MS) {
if (signal?.aborted) {
throw new Error(`SSH provider wait aborted for target "${targetId}".`)
}
if (getSshGitProvider(targetId) && getSshFilesystemProvider(targetId)) {
return
}
await new Promise((resolve) => setTimeout(resolve, SSH_PROVIDER_READY_INTERVAL_MS))
}
throw new Error(`SSH relay providers were not ready for target "${targetId}".`)
}
View on GitHub (pinned to 1136503c6a)
Solutions
- If the abort is expected (user cancelled), surface a 'Launch cancelled' state in the UI and stop retrying — do not treat this as a transient transport error.
- If the abort is coming from an overly tight caller timeout, lengthen or remove the caller's AbortSignal so the 10s SSH_PROVIDER_READY_TIMEOUT_MS budget can do its job.
- If providers are genuinely slow to register and you need more time, that is a different error (1041) — do not paper over it by aborting; investigate relay registration latency instead.
- Ensure only one connect attempt owns a given runtimeId at a time so a winning attempt does not abort a still-valid in-flight one.
Example fix
// before
const ctrl = new AbortController()
setTimeout(() => ctrl.abort(), 2_000) // too tight for relay bring-up
await connectRuntimeOwnedSshTarget({ runtimeId, connection, signal: ctrl.signal })
// after: let the provider-wait budget run; abort only on real user cancel
await connectRuntimeOwnedSshTarget({ runtimeId, connection, signal: userCancelSignal }) Defensive patterns
Strategy: try-catch
Validate before calling
import { getSshGitProvider, getSshFilesystemProvider } from './providers/ssh-dispatch'
// Before connect, there is nothing to validate (target not created yet).
// Instead, scope the abort to real user cancellation only.
const userCancel = new AbortController()
document.getElementById('cancel-launch').onclick = () => userCancel.abort()
// Do NOT add a short setTimeout(...).abort() here — the 10s provider-wait budget is intentional. Type guard
function isSshProviderWaitAborted(error: unknown): boolean {
return error instanceof Error && error.message.startsWith('SSH provider wait aborted for target ')
} Try / catch
try {
await connectRuntimeOwnedSshTarget({ runtimeId, connection, signal: userCancel.signal })
} catch (error) {
if (isSshProviderWaitAborted(error)) {
setLaunchState('cancelled') // user-cancelled, not a transport fault
return
}
throw error
} Prevention
- Only abort connectRuntimeOwnedSshTarget from a real user-cancel controller, never a short timeout.
- Serialise connect attempts per runtimeId so a winning attempt does not abort a still-valid in-flight one.
- Distinguish abort (1040) from provider-not-ready timeout (1041) in the UI — they need different responses.
When it happens
Trigger: connectRuntimeOwnedSshTarget is called with an AbortSignal (e.g. an ephemeral VM recipe is cancelled, the user closes the launching dialog, or a higher-level operation races and wins). During the <=10s window where getSshGitProvider(targetId) and getSshFilesystemProvider(targetId) are still undefined, signal.aborted flips true and the next loop iteration throws at ephemeral-vm-runtime-ssh.ts:63.
Common situations: User cancels an ephemeral VM / SSH recipe launch while the relay is still bringing up providers; a UI timeout on the launch surface aborts the connect; concurrent connect attempts to the same runtime where one wins and the other is aborted; tests that pass a short AbortSignal and do not await provider registration.
Related errors
- SSH relay providers were not ready for target "${targetId}".
- SSH target did not connect: ${state.status}
- Clone aborted
- ${response.error.message}
- Couldn't verify the SSH connection. Reconnect the host and t
AI-assisted analysis of stablyai/orca@1136503c6a (2026-08-12).
Data as JSON: /api/errors/5611024539c260a4.
Report an issue: GitHub.