{"record":{"id":"e68ca7884539a7ed","repo":"stablyai/orca","slug":"remote-folder-download-is-unavailable-reconnect-t","errorCode":null,"errorMessage":"Remote folder download is unavailable. Reconnect the SSH target and retry.","messagePattern":"Remote folder download is unavailable\\. Reconnect the SSH target and retry\\.","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"src/main/ipc/filesystem-download-folder.ts","lineNumber":60,"sourceCode":"    // Why: cleanup must not mask the transfer error, but a leaked recursive\n    // download tree needs enough visibility to diagnose and remove it.\n    console.warn(`[filesystem] Failed to remove temporary folder download '${dirPath}'`, error)\n  }\n}\n\n// Why: keep folder-download IPC out of filesystem.ts — that module is already large.\nexport function registerFilesystemDownloadFolderHandlers(): void {\n  ipcMain.handle(\n    'fs:downloadFolder',\n    async (\n      event,\n      args: { dirPath?: string; connectionId?: string }\n    ): Promise<DownloadFolderResult> => {\n      const dirPath = validateRequiredString(args?.dirPath, 'dirPath')\n      const connectionId = validateRequiredString(args?.connectionId, 'connectionId')\n      const provider = requireSshFilesystemProvider(connectionId)\n      if (!provider.downloadFolder) {\n        throw new Error(\n          'Remote folder download is unavailable. Reconnect the SSH target and retry.'\n        )\n      }\n      const abortController = new AbortController()\n      const abortOnSenderDestroyed = (): void => {\n        abortController.abort(new Error('Folder download canceled because the window closed'))\n      }\n      event.sender.once('destroyed', abortOnSenderDestroyed)\n      if (event.sender.isDestroyed()) {\n        abortOnSenderDestroyed()\n      }\n      try {\n        abortController.signal.throwIfAborted()\n        const remoteBasename = getRuntimePathBasename(dirPath)\n        const destinationBasename = sanitizeLocalDownloadFilename(remoteBasename)\n        const parentWindow = BrowserWindow.fromWebContents(event.sender) ?? undefined\n        // Why: after the local capability/abort checks, open the picker before\n        // remote tree validation so SSH latency does not delay click feedback.","sourceCodeStart":42,"sourceCodeEnd":78,"githubUrl":"https://github.com/stablyai/orca/blob/1136503c6a231a16dce8f921f6fadb63d181e8db/src/main/ipc/filesystem-download-folder.ts#L42-L78","documentation":"Thrown by the 'fs:downloadFolder' handler when requireSshFilesystemProvider(connectionId) returns a provider but that provider has no downloadFolder method. The SSH filesystem provider is registered per-connection, and not every transport/provider variant implements recursive folder download (it is an optional capability on IFilesystemProvider). The message tells the user to reconnect because a fresh connection typically rebuilds a full-capability provider.","triggerScenarios":"A connectionId resolves to a provider object that lacks the downloadFolder capability — e.g. a relay/system-SSH provider variant, a degraded provider after a partial reconnect, or a provider registered for a transport that only supports file ops.","commonSituations":"The SSH target was reconnected with a different/limited transport (ProxyCommand/FIDO2/system-SSH fallback) that does not implement folder download; a provider version skew between client and host; the connection is mid-migration and registered a stub provider.","solutions":["Click Reconnect on the SSH target so a fresh, full-capability provider is registered for the connection.","If reconnect still yields a provider without downloadFolder, the chosen transport does not support folder downloads — switch to a transport that does or use per-file download.","Download individual files instead of the folder if the capability is unavailable for this target."],"exampleFix":null,"handlingStrategy":"retry","validationCode":"// Before invoking downloadFolder, confirm the live provider exposes the capability\nimport { getSshFilesystemProvider } from '../providers/ssh-filesystem-dispatch'\nfunction canDownloadFolder(connectionId: string): boolean {\n  const p = getSshFilesystemProvider(connectionId)\n  return !!p && typeof p.downloadFolder === 'function'\n}","typeGuard":"function providerSupportsFolderDownload(p: unknown): p is { downloadFolder: Function } {\n  return !!p && typeof (p as any).downloadFolder === 'function'\n}","tryCatchPattern":"try {\n  await window.api.fs.downloadFolder({ dirPath, connectionId })\n} catch (e) {\n  if (e instanceof Error && /unavailable/i.test(e.message)) {\n    await reconnectSshTarget(connectionId)\n    // optionally retry once\n  } else throw e\n}","preventionTips":["Surface 'folder download unsupported' in the UI when the active transport lacks the capability instead of failing on invoke.","After any reconnect, re-check capabilities before offering the action.","Document which SSH transports support folder download so users pick an adequate one."],"tags":["ssh","capability","download","provider"],"backgroundTag":null,"analyzedSha":"1136503c6a231a16dce8f921f6fadb63d181e8db","analyzedAt":"2026-08-12T23:15:58.167Z","schemaVersion":2},"datasetVersion":"2026-08-12T23:17:12.415Z"}