stablyai/orca · error · Error
Cannot download a directory
Error message
Cannot download a directory
What it means
Thrown by the fs:downloadFile IPC handler when the SSH remote path resolves to a directory. The handler calls provider.stat on the remote path; if remoteStat.type is 'directory', the download is refused because the handler downloads individual files, not directory trees.
Source
Thrown at src/main/ipc/filesystem.ts:647
return { content: '', isBinary: true }
}
return { content: buffer.toString('utf-8'), isBinary: false }
}
)
ipcMain.handle(
'fs:downloadFile',
async (
event,
args: { filePath?: string; connectionId?: string }
): Promise<DownloadFileResult> => {
const filePath = validateRequiredString(args?.filePath, 'filePath')
const connectionId = validateRequiredString(args?.connectionId, 'connectionId')
const provider = requireSshFilesystemProvider(connectionId)
const remoteStat = await provider.stat(filePath)
if (remoteStat.type === 'directory') {
throw new Error('Cannot download a directory')
}
if (!provider.downloadFile) {
throw new Error('Remote file download is unavailable. Reconnect the SSH target and retry.')
}
const remoteBasename = getRuntimePathBasename(filePath)
const defaultPath = sanitizeLocalDownloadFilename(remoteBasename)
const parentWindow = BrowserWindow.fromWebContents(event.sender) ?? undefined
const dialogResult = parentWindow
? await dialog.showSaveDialog(parentWindow, { defaultPath })
: await dialog.showSaveDialog({ defaultPath })
if (dialogResult.canceled || !dialogResult.filePath) {
return { canceled: true }
}
const destinationPath = dialogResult.filePath
const { existed } = await inspectDownloadDestination(destinationPath)
const tempPath = createSiblingTransferPath(destinationPath, 'download')View on GitHub (pinned to 1136503c6a)
Solutions
- Select a file (not a directory) in the remote file browser before triggering download.
- If you need the entire directory, use scp/rsync from a terminal to recursively download it.
- In the renderer, check the entry type before enabling the download action.
Example fix
// before: download remote path /home/user/project (a directory) // after: download a specific file // /home/user/project/README.md // // or use scp for directories: // scp -r user@host:/home/user/project ./local-project
Defensive patterns
Strategy: type-guard
Validate before calling
// Before calling fs:downloadFile, check the remote entry type
async function assertRemoteIsFile(provider: SshFilesystemProvider, filePath: string): Promise<void> {
const st = await provider.stat(filePath)
if (st.type === 'directory') {
throw new Error(`${filePath} is a directory — select a file to download`)
}
}
// Or in the renderer, check the entry metadata:
// if (selectedEntry.type === 'directory') {
// showUserError('Select a file, not a directory')
// return
// } Type guard
function isRemoteFileEntry(entry: { type: string }): boolean {
return entry.type === 'file'
}
// Usage in renderer:
// if (!isRemoteFileEntry(selectedEntry)) {
// showUserError('Directories cannot be downloaded. Select a file.')
// return
// } Try / catch
try {
await ipcRenderer.invoke('fs:downloadFile', { filePath, connectionId })
} catch (error) {
if (error instanceof Error && error.message === 'Cannot download a directory') {
showUserError('Select a file to download. Use scp -r for directories.')
return
}
throw error
} Prevention
- Check the remote entry type in the file browser before enabling the download action.
- Disable or hide the download button for directory entries.
- For directory downloads, instruct users to use scp/rsync from a terminal.
When it happens
Trigger: Calling fs:downloadFile with a connectionId and filePath that points to a directory on the remote SSH host. The provider.stat call returns type 'directory' before the save dialog is shown.
Common situations: The user selects a directory entry in the remote file browser and triggers download. A path stored in state or clipboard is a directory rather than a file. The remote filesystem layout changed so a previously-file path is now a directory.
Related errors
- Cannot download to a directory
- Selected file is not a markdown document.
- ${label} is required
- Destination folder already exists
- Upload source changed while being inspected: ${sourcePath}
AI-assisted analysis of stablyai/orca@1136503c6a (2026-08-12).
Data as JSON: /api/errors/3fcdd052917b7527.
Report an issue: GitHub.