files-community/Files · error · FileNotFoundException
File was not found from path.
Error message
File was not found from path.
What it means
Thrown by FtpStorageService.GetFileAsync as FileNotFoundException. It connects, resolves the FTP path, and calls GetObjectInfo; if the result is null (path does not exist) or its Type is not FtpObjectType.File (e.g. the id actually names a directory), it cannot be returned as an IFile.
Source
Thrown at src/Files.App.Storage/Ftp/FtpStorageService.cs:35
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
- Confirm the path exists and is a file before resolving; fall back to GetFolderAsync if the id names a directory.
- Catch FileNotFoundException and show a clear 'file not available' message rather than a raw stack.
- Verify the server supports MLST/STAT (check FluentFTP server capabilities) or fall back to a LIST-based lookup.
- Re-resolve from a known parent folder by name to recover from renames.
Example fix
// before
var file = await service.GetFileAsync(id, ct);
// after
try { return await service.GetFileAsync(id, ct); }
catch (FileNotFoundException) {
try { return await service.GetFolderAsync(id, ct); }
catch { throw; }
} Defensive patterns
Strategy: validation
Validate before calling
// Validate the id is a file before resolving.
var ftpPath = FtpHelpers.GetFtpPath(id);
var info = await ftpClient.GetObjectInfo(ftpPath, token: ct);
if (info is null || info.Type != FtpObjectType.File)
throw new FileNotFoundException(id); Type guard
static async Task<bool> IsFtpFileAsync(AsyncFtpClient client, string path, CancellationToken ct)
{ var i = await client.GetObjectInfo(path, token: ct); return i is { Type: FtpObjectType.File }; } Try / catch
try { return await service.GetFileAsync(id, ct); }
catch (FileNotFoundException) { try { return await service.GetFolderAsync(id, ct); } catch { throw; } } Prevention
- Confirm the server supports MLST/STAT or fall back to LIST-based lookup.
- Validate deep-link/shell-activation ids are still valid before opening.
- Distinguish 'missing' from 'is a directory' by trying the folder variant.
When it happens
Trigger: GetFileAsync(id) where id resolves to a missing path or to a directory. Also when GetObjectInfo returns null due to the server not supporting STAT/MLST or denying access.
Common situations: Deep link / shell activation with a stale or moved file path; opening a path that is actually a folder; permission changes that hide the file from listings; FTP servers without MLST support returning null from GetObjectInfo for valid files.
Related errors
- Directory 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/1fdb93c5e475e82b.
Report an issue: GitHub.