AvaloniaUI/Avalonia · error · Error
StorageItem is not a file
Error message
StorageItem is not a file
What it means
Thrown by StorageItem.openRead when the item has no FileSystemFileHandle or its kind is not 'file'. openRead needs a real file handle (or a pre-attached File) to call getFile() and return its Blob; a directory or a handleless item cannot be read.
Source
Thrown at src/Browser/Avalonia.Browser/webapp/modules/storage/storageItem.ts:52
public static createFromHandle(handle: FileSystemFileHandle | FileSystemDirectoryHandle, bookmarkId?: string) {
return new StorageItem(handle, undefined, bookmarkId, undefined);
}
public static createFromFile(file: File) {
return new StorageItem(undefined, file, undefined, undefined);
}
public static createWellKnownDirectory(type: WellKnownDirectory) {
return new StorageItem(undefined, undefined, undefined, type);
}
public static async openRead(item: StorageItem): Promise<Blob> {
if (item.file) {
return item.file;
}
if (!item.handle || item.kind !== "file") {
throw new Error("StorageItem is not a file");
}
await item.verifyPermissions("read");
const file = await (item.handle as FileSystemFileHandle).getFile();
return file;
}
public static async openWrite(item: StorageItem): Promise<FileSystemWritableFileStream> {
if (!item.handle || item.kind !== "file") {
throw new Error("StorageItem is not a writeable file");
}
await item.verifyPermissions("readwrite");
return await (item.handle as FileSystemFileHandle).createWritable({ keepExistingData: false });
}
View on GitHub (pinned to 11c5427268)
Solutions
- Check item.kind === 'file' and item.handle (or item.file) before calling openRead.
- Obtain the item via getFile (directory.getFileHandle) rather than getFolder for files you intend to read.
- Filter directory entries out of iteration before attempting reads.
Example fix
// before
const blob = await StorageItem.openRead(item); // item is a directory
// after
if (item.kind !== 'file') throw new Error('expected a file item');
const blob = await StorageItem.openRead(item); Defensive patterns
Strategy: type-guard
Validate before calling
if (!item.file && (!item.handle || item.kind !== 'file')) {
throw new Error('StorageItem is not a file; cannot openRead');
} Type guard
function isReadableFileItem(item: StorageItem): boolean {
return item.kind === 'file' && (!!item.file || !!item.handle);
} Try / catch
try { return await StorageItem.openRead(item); }
catch (e) {
if (e instanceof Error && e.message === 'StorageItem is not a file') { /* prompt user to pick a file */ return null; }
throw e;
} Prevention
- Filter directory entries out before calling openRead.
- Use getFile (not getFolder) to obtain file items.
- Distinguish File-backed items from handle-backed items.
When it happens
Trigger: StorageItem.openRead(item) where item.handle is undefined AND item.file is undefined (so the early return on item.file is skipped), or item.kind === 'directory'. Calling openRead on a directory StorageItem or on a well-known-directory placeholder created via createWellKnownDirectory.
Common situations: User code passes a folder handle to a file-read API; a StorageItem built from createWellKnownDirectory (which has no handle/file) is misused for reading; a directory entry from getItemsIterator is handed to openRead.
Related errors
- StorageItem is not a writeable file
- Unable to create item in the requested directory
- Unable to move item to the requested directory
- Permissions denied
- Unable to access .NET memory
AI-assisted analysis of AvaloniaUI/Avalonia@11c5427268 (2026-08-13).
Data as JSON: /api/errors/320797b9c67c83fc.
Report an issue: GitHub.