{"record":{"id":"09368b4bd13aef5a","repo":"naptha/tesseract.js","slug":"legacy-model-requested-but-code-missing","errorCode":null,"errorMessage":"Legacy model requested but code missing.","messagePattern":"Legacy model requested but code missing\\.","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"src/createWorker.js","lineNumber":135,"sourceCode":"        cacheMethod: options.cacheMethod,\n        gzip: options.gzip,\n        lstmOnly: [OEM.DEFAULT, OEM.LSTM_ONLY].includes(currentOem)\n          && !options.legacyLang,\n      },\n    },\n  }));\n\n  const initializeInternal = (_langs, _oem, _config, jobId) => (\n    startJob(createJob({\n      id: jobId,\n      action: 'initialize',\n      payload: { langs: _langs, oem: _oem, config: _config },\n    }))\n  );\n\n  const reinitialize = (langs = 'eng', oem, config, jobId) => { // eslint-disable-line\n\n    if (lstmOnlyCore && [OEM.TESSERACT_ONLY, OEM.TESSERACT_LSTM_COMBINED].includes(oem)) throw Error('Legacy model requested but code missing.');\n\n    const _oem = oem || currentOem;\n    currentOem = _oem;\n\n    const _config = config || currentConfig;\n    currentConfig = _config;\n\n    // Only load langs that are not already loaded.\n    // This logic fails if the user downloaded the LSTM-only English data for a language\n    // and then uses `worker.reinitialize` to switch to the Legacy engine.\n    // However, the correct data will still be downloaded after initialization fails\n    // and this can be avoided entirely if the user loads the correct data ahead of time.\n    const langsArr = typeof langs === 'string' ? langs.split('+') : langs;\n    const _langs = langsArr.filter((x) => !currentLangs.includes(x));\n    currentLangs.push(..._langs);\n\n    if (_langs.length > 0) {\n      return loadLanguageInternal(_langs, jobId)","sourceCodeStart":117,"sourceCodeEnd":153,"githubUrl":"https://github.com/naptha/tesseract.js/blob/a1ca80d9e31c34512d0ded75ff8821ddcf3f2f91/src/createWorker.js#L117-L153","documentation":"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.","triggerScenarios":"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).","commonSituations":"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.","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."],"exampleFix":"// before\nconst worker = await createWorker('eng'); // lstmOnlyCore = true\nawait worker.reinitialize('eng', OEM.TESSERACT_ONLY); // throws\n\n// after\nconst worker = await createWorker('eng', OEM.TESSERACT_ONLY, { legacyCore: true, legacyLang: true });\nawait worker.reinitialize('eng', OEM.TESSERACT_ONLY);","handlingStrategy":"validation","validationCode":"const OEM = require('tesseract.js').OEM;\nconst LEGACY_OEMS = new Set([OEM.TESSERACT_ONLY, OEM.TESSERACT_LSTM_COMBINED]);\n// legacyNeeded must match the legacyCore flag passed at createWorker time\nfunction assertLegacyAvailable(legacyCoreEnabled, requestedOem) {\n  if (!legacyCoreEnabled && LEGACY_OEMS.has(requestedOem)) {\n    throw new Error('Recreate the worker with legacyCore:true before requesting OEM ' + requestedOem);\n  }\n}\nassertLegacyAvailable(options.legacyCore === true, requestedOem);\nawait worker.reinitialize(langs, requestedOem);","typeGuard":"const isLegacyOem = (oem) =>\n  oem === 0 /* TESSERACT_ONLY */ || oem === 2 /* TESSERACT_LSTM_COMBINED */;","tryCatchPattern":"try {\n  await worker.reinitialize(langs, requestedOem);\n} catch (e) {\n  if (/Legacy model requested/.test(e.message)) {\n    // recreate with legacy support, then retry\n    await worker.terminate();\n    worker = await createWorker(langs, requestedOem, { legacyCore: true, legacyLang: true });\n  } else { throw e; }\n}","preventionTips":["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."],"tags":["oem","legacy-core","reinitialize","configuration"],"backgroundTag":null,"analyzedSha":"a1ca80d9e31c34512d0ded75ff8821ddcf3f2f91","analyzedAt":"2026-08-13T04:28:13.744Z","schemaVersion":2},"datasetVersion":"2026-08-13T09:17:06.757Z"}