naptha/tesseract.js · error · Error
File could not be read! Code=${code}
Error message
File could not be read! Code=${code} What it means
In the browser worker's loadImage, File/Blob/Canvas inputs flow through readFromBlobOrFile, which uses FileReader.readAsArrayBuffer. If the reader's onerror fires, the promise rejects with the FileReader error code. Standard DOM error codes: 1=NOT_FOUND_ERR, 2=SECURITY_ERR, 3=ABORT_ERR, 4=NOT_READABLE_ERR, 12=SYNTAX_ERR, 13=ENCODING_ERR.
Source
Thrown at src/worker/browser/loadImage.js:17
'use strict';
/**
* readFromBlobOrFile
*
* @name readFromBlobOrFile
* @function
* @access private
*/
const readFromBlobOrFile = (blob) => (
new Promise((resolve, reject) => {
const fileReader = new FileReader();
fileReader.onload = () => {
resolve(fileReader.result);
};
fileReader.onerror = ({ target: { error: { code } } }) => {
reject(Error(`File could not be read! Code=${code}`));
};
fileReader.readAsArrayBuffer(blob);
})
);
/**
* loadImage
*
* @name loadImage
* @function load image from different source
* @access private
*/
const loadImage = async (image) => {
let data = image;
if (typeof image === 'undefined') {
return 'undefined';
}
View on GitHub (pinned to a1ca80d9e3)
Solutions
- Map the code: 1 -> file missing, 2 -> security/tainted, 4 -> permissions/lock; act accordingly (re-prompt, fix CORS, release lock).
- Do not call URL.revokeObjectURL on a blob URL before passing the blob to the worker.
- For cross-origin canvas sources, set img.crossOrigin = 'anonymous' and serve images with proper CORS headers.
- Validate the File/Blob is non-empty and still readable (size > 0, type set) before handing it to recognize/detect.
Example fix
// before const url = URL.createObjectURL(blob); URL.revokeObjectURL(url); // revoked too early await worker.recognize(blob); // code 4 / security // after const url = URL.createObjectURL(blob); await worker.recognize(blob); URL.revokeObjectURL(url); // revoke only after recognize resolves
Defensive patterns
Strategy: validation
Validate before calling
// Validate File/Blob is non-empty and still readable before handing it to the worker.
function assertReadableBlob(blob) {
if (!(blob instanceof Blob)) throw new Error('Expected Blob/File');
if (blob.size === 0) throw new Error('Blob is empty');
if (blob.isClosed) throw new Error('Blob is closed');
}
assertReadableBlob(file);
await worker.recognize(file); Type guard
const isReadableFile = (f) => (f instanceof File || f instanceof Blob) && f.size > 0 && !f.isClosed;
Try / catch
const FILE_ERROR_CODES = { 1: 'NOT_FOUND', 2: 'SECURITY', 3: 'ABORT', 4: 'NOT_READABLE' };
try {
await worker.recognize(file);
} catch (e) {
const m = e.message.match(/Code=(\d+)/);
if (m && FILE_ERROR_CODES[m[1]] === 'NOT_READABLE') {
// prompt user to re-select the file, then retry
return;
}
throw e;
} Prevention
- Do not call URL.revokeObjectURL on a blob URL until after recognize/detect resolves.
- For cross-origin canvas sources, set img.crossOrigin = 'anonymous' and require CORS headers.
- When accepting user-selected files, copy/snapshot the bytes immediately rather than holding the File handle.
- Map the FileReader error code to a cause (1 missing, 2 security, 4 unreadable) before retrying.
When it happens
Trigger: Passing a File whose underlying file was moved/deleted after selection; a Blob backed by a revoked object URL; a cross-origin-tainted canvas; a file the OS refuses to read (permissions/lock); an aborted read.
Common situations: User selects a file in an <input type=file> then the file disappears; URL.createObjectURL blob revoked too early; canvas drawn with cross-origin images without crossOrigin='anonymous'; security policy in the worker context blocking file reads.
Related errors
AI-assisted analysis of naptha/tesseract.js@a1ca80d9e3 (2026-08-13).
Data as JSON: /api/errors/d680091e1f7e7e95.
Report an issue: GitHub.