{"record":{"id":"97e0c6dd3b8669bd","repo":"stablyai/orca","slug":"ssh-target-args-targetid-not-found","errorCode":null,"errorMessage":"SSH target \"${args.targetId}\" not found","messagePattern":"SSH target \"(.+?)\" not found","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"src/main/ipc/ssh.ts","lineNumber":1421,"sourceCode":"        const appPtyId = toAppSshPtyId(targetId, ptyId)\n        clearProviderPtyState(appPtyId)\n        deletePtyOwnership(appPtyId)\n      }\n      // Why: reset's connect() may trip onCredentialRequest; clear so a later non-prompting doConnect doesn't persist lastRequiredPassphrase=true.\n      credentialRequestedForTarget.delete(targetId)\n      await connectionManager!.disconnect(targetId)\n    }\n  }\n\n  ipcMain.handle('ssh:resetRelay', (_event, args: { targetId: string }) => {\n    const existingReset = resetRelayInFlight.get(args.targetId)\n    if (existingReset) {\n      return existingReset\n    }\n\n    const target = sshStore!.getTarget(args.targetId)\n    if (!target) {\n      throw new Error(`SSH target \"${args.targetId}\" not found`)\n    }\n    // Why: reset opens its own transport, so it must be fenced by shutdown the same way connect is.\n    assertSshConnectsNotFenced()\n\n    let resetPromise: Promise<void>\n    resetPromise = runTargetLifecycle(args.targetId, () =>\n      doResetRelay(args.targetId, target)\n    ).finally(() => {\n      if (resetRelayInFlight.get(args.targetId) === resetPromise) {\n        resetRelayInFlight.delete(args.targetId)\n      }\n    })\n    resetRelayInFlight.set(args.targetId, resetPromise)\n    return resetPromise\n  })\n\n  ipcMain.handle('ssh:getState', (_event, args: { targetId: string }) => {\n    return getPublicSshState(args.targetId)","sourceCodeStart":1403,"sourceCodeEnd":1439,"githubUrl":"https://github.com/stablyai/orca/blob/1136503c6a231a16dce8f921f6fadb63d181e8db/src/main/ipc/ssh.ts#L1403-L1439","documentation":"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.","triggerScenarios":"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.","commonSituations":"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.","solutions":["Refresh the target list in the renderer and only resetRelay for an existing targetId.","If the target was removed, dismiss any reset affordance tied to it.","Validate the targetId against the current sshStore before calling resetRelay."],"exampleFix":null,"handlingStrategy":"validation","validationCode":"const targets = await ipcRenderer.invoke('ssh:listTargets')\nif (!targets.some((t) => t.id === targetId)) {\n  showNotification('SSH target not found; refresh the list.')\n  return\n}\nawait ipcRenderer.invoke('ssh:resetRelay', { targetId })","typeGuard":null,"tryCatchPattern":"try {\n  await ipcRenderer.invoke('ssh:resetRelay', { targetId })\n} catch (e) {\n  if (/SSH target .* not found/.test((e as Error).message)) {\n    refreshTargetList()\n  } else throw e\n}","preventionTips":["Refresh the target list before exposing a reset-relay control.","Disable the reset action when the targetId is not in the current list.","Cancel pending reset requests when the owning target is deleted."],"tags":["ssh","validation","not-found","relay","ipc"],"backgroundTag":null,"analyzedSha":"1136503c6a231a16dce8f921f6fadb63d181e8db","analyzedAt":"2026-08-12T23:15:58.167Z","schemaVersion":2},"datasetVersion":"2026-08-12T23:17:12.415Z"}