{"record":{"id":"4e69b88894bee87f","repo":"Stirling-Tools/Stirling-PDF","slug":"ocr-tools-ocrmypdf-or-tesseract-are-not-installe","errorCode":null,"errorMessage":"OCR tools (OCRmyPDF or Tesseract) are not installed on the server. Use the standard or fat Docker image instead of ultra-lite, or install OCR tools manually.","messagePattern":"OCR tools \\(OCRmyPDF or Tesseract\\) are not installed on the server\\. Use the standard or fat Docker image instead of ultra-lite, or install OCR tools manually\\.","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"frontend/editor/src/core/hooks/tools/ocr/useOCROperation.ts","lineNumber":137,"sourceCode":"    } catch {\n      /* ignore and try local extractor */\n    }\n    try {\n      const local = await extractZipFile(blob); // local fallback\n      if (local.length > 0) return local;\n    } catch {\n      /* fall through */\n    }\n    return [new File([blob], `ocr_${base}.zip`, { type: \"application/zip\" })];\n  }\n\n  // Not a PDF: surface error details if present\n  if (!head.startsWith(\"%PDF\")) {\n    const textBuf = await blob.slice(0, 1024).arrayBuffer();\n    const text = new TextDecoder().decode(new Uint8Array(textBuf));\n    if (/error|exception|html/i.test(text)) {\n      if (text.includes(\"OCR tools\") && text.includes(\"not installed\")) {\n        throw new Error(\n          \"OCR tools (OCRmyPDF or Tesseract) are not installed on the server. Use the standard or fat Docker image instead of ultra-lite, or install OCR tools manually.\",\n        );\n      }\n      const title =\n        text.match(/<title[^>]*>([^<]+)<\\/title>/i)?.[1] ||\n        text.match(/<h1[^>]*>([^<]+)<\\/h1>/i)?.[1] ||\n        \"Unknown error\";\n      throw new Error(`OCR service error: ${title}`);\n    }\n    throw new Error(`Response is not a valid PDF. Header: \"${head}\"`);\n  }\n\n  const originalName = originalFiles[0].name;\n  return [new File([blob], originalName, { type: \"application/pdf\" })];\n};\n\n// Static configuration object (without t function dependencies)\nexport const ocrOperationConfig = defineSingleFileTool({","sourceCodeStart":119,"sourceCodeEnd":155,"githubUrl":"https://github.com/Stirling-Tools/Stirling-PDF/blob/9ef20dcab80b85041912f045e17a6aea1d08f969/frontend/editor/src/core/hooks/tools/ocr/useOCROperation.ts#L119-L155","documentation":"Thrown by the OCR response handler when the backend response is not a PDF or ZIP (so it reads up to 1KB of text) and the text contains both 'OCR tools' and 'not installed'. This is the server's own error message surfacing that the running Stirling image (ultra-lite) was built without OCRmyPDF/Tesseract, so the OCR endpoint cannot function.","triggerScenarios":"User runs OCR against a backend deployed from the ultra-lite Docker image, which intentionally omits OCR dependencies to minimize size; the OCR endpoint detects the missing binaries and returns an HTML/text error body instead of a PDF.","commonSituations":"Self-hosting with ultra-lite for size and forgetting OCR is excluded; ops switched images to ultra-lite for a smaller footprint; CI/test environment using ultra-lite by default.","solutions":["Deploy the standard or fat Docker image, which bundle OCRmyPDF and Tesseract.","If ultra-lite must stay, install OCRmyPDF/Tesseract into the container at build time (custom Dockerfile FROM the ultra-lite image).","Hide/disable the OCR tool in the frontend when the backend advertises no OCR support (check app-config capability flags).","Show the mapped user-facing message (already done) plus a docs link on how to switch images."],"exampleFix":"// before — only thrown once the bad body is parsed\nif (text.includes(\"OCR tools\") && text.includes(\"not installed\")) {\n  throw new Error(\"OCR tools (OCRmyPDF or Tesseract) are not installed on the server. Use the standard or fat Docker image instead of ultra-lite, or install OCR tools manually.\");\n}\n\n// after — also gate the tool up front so the call is never made\n// (in the tool's isEnabled / validateParams):\nif (!appConfig.ocrAvailable) {\n  throw new Error(\"OCR is not available on this server image. Use the standard or fat Docker image.\");\n}","handlingStrategy":"validation","validationCode":"// Gate OCR on backend capability before calling the endpoint\nif (!appConfig.ocrAvailable) {\n  // show 'OCR not available on this server image'; do not POST\n}","typeGuard":"function ocrAvailable(cfg: { ocrAvailable?: boolean } | null | undefined): boolean {\n  return !!cfg && cfg.ocrAvailable === true;\n}","tryCatchPattern":"try {\n  await runOcr();\n} catch (e) {\n  if (e instanceof Error && e.message.includes(\"OCR tools\") && e.message.includes(\"not installed\")) {\n    toast.error(\"OCR is not installed. Use the standard or fat Docker image.\");\n  } else throw e;\n}","preventionTips":["Deploy the standard or fat Docker image (which bundle OCRmyPDF/Tesseract) when OCR is needed.","Hide the OCR tool when the backend advertises no OCR support.","Document the image dependency in the OCR tool's tooltip/help."],"tags":["ocr","docker","deployment","missing-dependency"],"backgroundTag":null,"analyzedSha":"9ef20dcab80b85041912f045e17a6aea1d08f969","analyzedAt":"2026-08-13T22:11:39.827Z","schemaVersion":2},"datasetVersion":"2026-08-14T00:17:13.853Z"}