files-community/Files · error · DirectoryNotFoundException
Directory was not found from path.
Error message
Directory was not found from path.
What it means
Thrown by FtpStorageService.GetFolderAsync as DirectoryNotFoundException. After connecting and resolving the path via FtpHelpers.GetFtpPath, it calls GetObjectInfo; if the object is null (no such path) or is not a FtpObjectType.Directory (e.g. the id points at a file), it cannot be returned as an IFolder.
Source
Thrown at src/Files.App.Storage/Ftp/FtpStorageService.cs:21
using FluentFTP;
using System.IO;
namespace Files.App.Storage
{
/// <inheritdoc cref="IFtpStorageService"/>
public sealed class FtpStorageService : IFtpStorageService
{
/// <inheritdoc/>
public async Task<IFolder> GetFolderAsync(string id, CancellationToken cancellationToken = default)
{
using var ftpClient = FtpHelpers.GetFtpClient(id);
await ftpClient.EnsureConnectedAsync(cancellationToken);
var ftpPath = FtpHelpers.GetFtpPath(id);
var item = await ftpClient.GetObjectInfo(ftpPath, token: cancellationToken);
if (item is null || item.Type != FtpObjectType.Directory)
throw new DirectoryNotFoundException("Directory was not found from path.");
return new FtpStorageFolder(ftpPath, item.Name, null);
}
/// <inheritdoc/>
public async Task<IFile> GetFileAsync(string id, CancellationToken cancellationToken = default)
{
using var ftpClient = FtpHelpers.GetFtpClient(id);
await ftpClient.EnsureConnectedAsync(cancellationToken);
var ftpPath = FtpHelpers.GetFtpPath(id);
var item = await ftpClient.GetObjectInfo(ftpPath, token: cancellationToken);
if (item is null || item.Type != FtpObjectType.File)
throw new FileNotFoundException("File was not found from path.");
return new FtpStorageFile(ftpPath, item.Name, null);
}
}View on GitHub (pinned to 68c68a58d4)
Solutions
- Validate the id format with FtpHelpers before calling; confirm the host/path are correct.
- Call GetFileAsync as a fallback - the id may point to a file rather than a folder.
- Catch DirectoryNotFoundException and present a 'location no longer available' message, offering to browse the parent.
- Verify the FTP account has list permission on the target directory so GetObjectInfo can resolve it.
Example fix
// before
var folder = await service.GetFolderAsync(id, ct);
// after
try { return await service.GetFolderAsync(id, ct); }
catch (DirectoryNotFoundException) {
if (await ExistsAsync(service, id, ct))
return await service.GetFileAsync(id, ct); // it was a file, not a folder
throw;
} Defensive patterns
Strategy: validation
Validate before calling
// Validate the id is a directory before resolving.
var ftpPath = FtpHelpers.GetFtpPath(id);
var info = await ftpClient.GetObjectInfo(ftpPath, token: ct);
if (info is null || info.Type != FtpObjectType.Directory)
throw new DirectoryNotFoundException(id); Type guard
static async Task<bool> IsFtpDirectoryAsync(AsyncFtpClient client, string path, CancellationToken ct)
{ var i = await client.GetObjectInfo(path, token: ct); return i is { Type: FtpObjectType.Directory }; } Try / catch
try { return await service.GetFolderAsync(id, ct); }
catch (DirectoryNotFoundException) { /* offer to open parent or the file variant */ throw; } Prevention
- Confirm list/STAT permission so GetObjectInfo can resolve the path.
- Distinguish 'deleted' from 'is a file' by trying GetFileAsync as a fallback.
- Refresh stale bookmarks/ids after server-side reorganization.
When it happens
Trigger: GetFolderAsync(id) where id resolves to a non-existent FTP path, or to a path that exists but is a file rather than a directory. Also if GetObjectInfo returns null because the server denied the listing/STAT.
Common situations: Bookmark/pinned location pointing at a deleted or renamed folder; user typing a path that is actually a file; permission settings that hide the entry from STAT/MLST; stale cached ids after server-side reorganization.
Related errors
- File was not found from path.
- Copying folders is not supported.
- File already exists.
- Couldn't generate unique name. File skipped.
- File creation failed.
AI-assisted analysis of files-community/Files@68c68a58d4 (2026-08-13).
Data as JSON: /api/errors/410ed1f59aba1399.
Report an issue: GitHub.