stablyai/orca · error

SSH target "${args.targetId}" not found

Error message

SSH target "${args.targetId}" not found

What it means

Thrown by the 'ssh:resetRelay' IPC handler when sshStore.getTarget(args.targetId) returns undefined. resetRelay rebuilds the relay transport for a target, so it needs the saved target configuration (host, user, port, auth). A missing target means the targetId is unknown to the store, and the reset cannot proceed because there is nothing to reset.

Source

Thrown at src/main/ipc/ssh.ts:1421

        const appPtyId = toAppSshPtyId(targetId, ptyId)
        clearProviderPtyState(appPtyId)
        deletePtyOwnership(appPtyId)
      }
      // Why: reset's connect() may trip onCredentialRequest; clear so a later non-prompting doConnect doesn't persist lastRequiredPassphrase=true.
      credentialRequestedForTarget.delete(targetId)
      await connectionManager!.disconnect(targetId)
    }
  }

  ipcMain.handle('ssh:resetRelay', (_event, args: { targetId: string }) => {
    const existingReset = resetRelayInFlight.get(args.targetId)
    if (existingReset) {
      return existingReset
    }

    const target = sshStore!.getTarget(args.targetId)
    if (!target) {
      throw new Error(`SSH target "${args.targetId}" not found`)
    }
    // Why: reset opens its own transport, so it must be fenced by shutdown the same way connect is.
    assertSshConnectsNotFenced()

    let resetPromise: Promise<void>
    resetPromise = runTargetLifecycle(args.targetId, () =>
      doResetRelay(args.targetId, target)
    ).finally(() => {
      if (resetRelayInFlight.get(args.targetId) === resetPromise) {
        resetRelayInFlight.delete(args.targetId)
      }
    })
    resetRelayInFlight.set(args.targetId, resetPromise)
    return resetPromise
  })

  ipcMain.handle('ssh:getState', (_event, args: { targetId: string }) => {
    return getPublicSshState(args.targetId)

View on GitHub (pinned to 1136503c6a)

Solutions

  1. Refresh the target list in the renderer and only resetRelay for an existing targetId.
  2. If the target was removed, dismiss any reset affordance tied to it.
  3. Validate the targetId against the current sshStore before calling resetRelay.
Defensive patterns

Strategy: validation

Validate before calling

const targets = await ipcRenderer.invoke('ssh:listTargets')
if (!targets.some((t) => t.id === targetId)) {
  showNotification('SSH target not found; refresh the list.')
  return
}
await ipcRenderer.invoke('ssh:resetRelay', { targetId })

Try / catch

try {
  await ipcRenderer.invoke('ssh:resetRelay', { targetId })
} catch (e) {
  if (/SSH target .* not found/.test((e as Error).message)) {
    refreshTargetList()
  } else throw e
}

Prevention

When it happens

Trigger: Renderer invokes 'ssh:resetRelay' with a targetId that was deleted, never configured, or is stale after a config sync. The in-flight dedupe (resetRelayInFlight) passed but the store lookup failed.

Common situations: Stale targetId in renderer state after the user removed the target. Window-state persistence replaying an old ID. Concurrent removal racing with a reset attempt.

Related errors


AI-assisted analysis of stablyai/orca@1136503c6a (2026-08-12). Data as JSON: /api/errors/97e0c6dd3b8669bd. Report an issue: GitHub.