toeverything/AFFiNE · error · DOMException
NotReadableError
NotReadableError
Error message
File could not be read
What it means
snapshotFile retries file.arrayBuffer() three times for transient NotReadable errors and this DOMException fires only if all attempts failed or the loop exited without bytes, i.e. the File handle stayed unreadable (e.g. file moved/deleted on disk mid-read).
Source
Thrown at blocksuite/affine/shared/src/utils/file/filesys.ts:198
function sleep(ms: number) {
return new Promise(resolve => setTimeout(resolve, ms));
}
export async function snapshotFile(file: File, relativePath?: string) {
let bytes: Uint8Array | null = null;
for (let attempt = 0; attempt < 3; attempt++) {
try {
bytes = new Uint8Array(await file.arrayBuffer());
break;
} catch (error) {
if (!isNotReadableError(error) || attempt === 2) {
throw error;
}
await sleep(100 * (attempt + 1));
}
}
if (!bytes) {
throw new DOMException('File could not be read', 'NotReadableError');
}
const snapshot = new File([copyToArrayBuffer(bytes)], file.name, {
type: file.type,
lastModified: file.lastModified,
});
const path = relativePath ?? file.webkitRelativePath;
if (path) {
Object.defineProperty(snapshot, 'webkitRelativePath', {
value: path,
writable: false,
});
}
return snapshot;
}
export async function snapshotFiles(files: File[]) {
const results = await Promise.allSettled(
files.map(file => snapshotFile(file))View on GitHub (pinned to b4c8548c09)
Solutions
- Verify the File/Blob object is still valid and not already consumed by a previous read; re-obtain the file handle before reading.
- Check that the file actually exists and is readable (permissions, path) before calling file.arrayBuffer() or FileReader.readAsArrayBuffer.
- Handle the DOMException from the underlying FileReader by surfacing its message to the user so they can retry or pick a different file.
Example fix
async function readFile(file: File): Promise<ArrayBuffer> {
if (!file || file.size === 0) throw new Error('Empty file selected');
try {
return await file.arrayBuffer();
} catch (e) {
throw new Error(`File could not be read: ${(e as Error).message}`);
}
} Defensive patterns
Strategy: retry
When it happens
Trigger: Thrown at blocksuite/affine/shared/src/utils/file/filesys.ts:198 when the library encounters an invalid state.
Common situations: See trigger scenarios.
AI-assisted analysis of toeverything/AFFiNE@b4c8548c09 (2026-08-18).
Data as JSON: /api/errors/bd0459e5b3e9c1ad.
Report an issue: GitHub.