{"record":{"id":"1fdb93c5e475e82b","repo":"files-community/Files","slug":"file-was-not-found-from-path","errorCode":null,"errorMessage":"File was not found from path.","messagePattern":"File was not found from path\\.","errorType":"exception","errorClass":"FileNotFoundException","httpStatus":null,"severity":"error","filePath":"src/Files.App.Storage/Ftp/FtpStorageService.cs","lineNumber":35,"sourceCode":"\n\t\t\tvar ftpPath = FtpHelpers.GetFtpPath(id);\n\t\t\tvar item = await ftpClient.GetObjectInfo(ftpPath, token: cancellationToken);\n\t\t\tif (item is null || item.Type != FtpObjectType.Directory)\n\t\t\t\tthrow new DirectoryNotFoundException(\"Directory was not found from path.\");\n\n\t\t\treturn new FtpStorageFolder(ftpPath, item.Name, null);\n\t\t}\n\n\t\t/// <inheritdoc/>\n\t\tpublic async Task<IFile> GetFileAsync(string id, CancellationToken cancellationToken = default)\n\t\t{\n\t\t\tusing var ftpClient = FtpHelpers.GetFtpClient(id);\n\t\t\tawait ftpClient.EnsureConnectedAsync(cancellationToken);\n\n\t\t\tvar ftpPath = FtpHelpers.GetFtpPath(id);\n\t\t\tvar item = await ftpClient.GetObjectInfo(ftpPath, token: cancellationToken);\n\t\t\tif (item is null || item.Type != FtpObjectType.File)\n\t\t\t\tthrow new FileNotFoundException(\"File was not found from path.\");\n\n\t\t\treturn new FtpStorageFile(ftpPath, item.Name, null);\n\t\t}\n\t}\n}\n","sourceCodeStart":17,"sourceCodeEnd":41,"githubUrl":"https://github.com/files-community/Files/blob/68c68a58d4d6a5f7197e07c8fff85cfd4279c78b/src/Files.App.Storage/Ftp/FtpStorageService.cs#L17-L41","documentation":"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.","triggerScenarios":"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.","commonSituations":"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.","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."],"exampleFix":"// before\nvar file = await service.GetFileAsync(id, ct);\n\n// after\ntry { return await service.GetFileAsync(id, ct); }\ncatch (FileNotFoundException) {\n    try { return await service.GetFolderAsync(id, ct); }\n    catch { throw; }\n}","handlingStrategy":"validation","validationCode":"// Validate the id is a file before resolving.\nvar ftpPath = FtpHelpers.GetFtpPath(id);\nvar info = await ftpClient.GetObjectInfo(ftpPath, token: ct);\nif (info is null || info.Type != FtpObjectType.File)\n    throw new FileNotFoundException(id);","typeGuard":"static async Task<bool> IsFtpFileAsync(AsyncFtpClient client, string path, CancellationToken ct)\n{ var i = await client.GetObjectInfo(path, token: ct); return i is { Type: FtpObjectType.File }; }","tryCatchPattern":"try { return await service.GetFileAsync(id, ct); }\ncatch (FileNotFoundException) { try { return await service.GetFolderAsync(id, ct); } catch { throw; } }","preventionTips":["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."],"tags":["ftp","storage","navigation","notfound"],"backgroundTag":null,"analyzedSha":"68c68a58d4d6a5f7197e07c8fff85cfd4279c78b","analyzedAt":"2026-08-13T10:34:54.614Z","schemaVersion":2},"datasetVersion":"2026-08-13T14:17:21.547Z"}