naptha/tesseract.js · error · Error
Legacy model requested but code missing.
Error message
Legacy model requested but code missing.
What it means
lstmOnlyCore (src/createWorker.js:36) is true when the worker was created with OEM.DEFAULT or OEM.LSTM_ONLY and the legacyCore option is not set — meaning the loaded WASM core has no legacy engine. reinitialize() throws when you then request OEM.TESSERACT_ONLY (0) or OEM.TESSERACT_LSTM_COMBINED (2), because those modes require the legacy engine that is absent from the LSTM-only core build.
Source
Thrown at src/createWorker.js:135
cacheMethod: options.cacheMethod,
gzip: options.gzip,
lstmOnly: [OEM.DEFAULT, OEM.LSTM_ONLY].includes(currentOem)
&& !options.legacyLang,
},
},
}));
const initializeInternal = (_langs, _oem, _config, jobId) => (
startJob(createJob({
id: jobId,
action: 'initialize',
payload: { langs: _langs, oem: _oem, config: _config },
}))
);
const reinitialize = (langs = 'eng', oem, config, jobId) => { // eslint-disable-line
if (lstmOnlyCore && [OEM.TESSERACT_ONLY, OEM.TESSERACT_LSTM_COMBINED].includes(oem)) throw Error('Legacy model requested but code missing.');
const _oem = oem || currentOem;
currentOem = _oem;
const _config = config || currentConfig;
currentConfig = _config;
// Only load langs that are not already loaded.
// This logic fails if the user downloaded the LSTM-only English data for a language
// and then uses `worker.reinitialize` to switch to the Legacy engine.
// However, the correct data will still be downloaded after initialization fails
// and this can be avoided entirely if the user loads the correct data ahead of time.
const langsArr = typeof langs === 'string' ? langs.split('+') : langs;
const _langs = langsArr.filter((x) => !currentLangs.includes(x));
currentLangs.push(..._langs);
if (_langs.length > 0) {
return loadLanguageInternal(_langs, jobId)View on GitHub (pinned to a1ca80d9e3)
Solutions
- Recreate the worker with legacyCore: true in options so the full core is loaded, then reinitialize to TESSERACT_ONLY/COMBINED.
- Create the worker directly with OEM.TESSERACT_ONLY or OEM.TESSERACT_LSTM_COMBINED instead of reinitializing.
- Keep reinitialize on OEM.LSTM_ONLY or OEM.DEFAULT, which the LSTM-only core supports.
Example fix
// before
const worker = await createWorker('eng'); // lstmOnlyCore = true
await worker.reinitialize('eng', OEM.TESSERACT_ONLY); // throws
// after
const worker = await createWorker('eng', OEM.TESSERACT_ONLY, { legacyCore: true, legacyLang: true });
await worker.reinitialize('eng', OEM.TESSERACT_ONLY); Defensive patterns
Strategy: validation
Validate before calling
const OEM = require('tesseract.js').OEM;
const LEGACY_OEMS = new Set([OEM.TESSERACT_ONLY, OEM.TESSERACT_LSTM_COMBINED]);
// legacyNeeded must match the legacyCore flag passed at createWorker time
function assertLegacyAvailable(legacyCoreEnabled, requestedOem) {
if (!legacyCoreEnabled && LEGACY_OEMS.has(requestedOem)) {
throw new Error('Recreate the worker with legacyCore:true before requesting OEM ' + requestedOem);
}
}
assertLegacyAvailable(options.legacyCore === true, requestedOem);
await worker.reinitialize(langs, requestedOem); Type guard
const isLegacyOem = (oem) => oem === 0 /* TESSERACT_ONLY */ || oem === 2 /* TESSERACT_LSTM_COMBINED */;
Try / catch
try {
await worker.reinitialize(langs, requestedOem);
} catch (e) {
if (/Legacy model requested/.test(e.message)) {
// recreate with legacy support, then retry
await worker.terminate();
worker = await createWorker(langs, requestedOem, { legacyCore: true, legacyLang: true });
} else { throw e; }
} Prevention
- Decide upfront whether you will ever need the legacy engine; if yes, set legacyCore:true and legacyLang:true at createWorker.
- Track the OEM/OEM-core mode of each worker instance in your own state so reinitialize targets stay valid.
- Avoid mixing LSTM-only workers with legacy OEM calls; segregate workers by engine mode.
When it happens
Trigger: worker.reinitialize('eng', OEM.TESSERACT_ONLY) or worker.reinitialize('eng', OEM.TESSERACT_LSTM_COMBINED) on a worker created with default options (OEM.LSTM_ONLY, no legacyCore).
Common situations: Starting with the default LSTM-only setup and later wanting legacy accuracy; following a guide that switches OEM at runtime without setting legacyCore; not knowing the core build is tied to creation-time options.
Related errors
- `worker.detect` requires Legacy model, which was not loaded.
- initialization failed
- Failed to load TesseractCore
AI-assisted analysis of naptha/tesseract.js@a1ca80d9e3 (2026-08-13).
Data as JSON: /api/errors/09368b4bd13aef5a.
Report an issue: GitHub.