Stirling-Tools/Stirling-PDF · error · Error
OCR service error: ${title}
Error message
OCR service error: ${title} What it means
Thrown by the OCR response handler when the response is not a PDF/ZIP but its first 1KB matches /error|exception|html/ and does not match the OCR-tools-not-installed substring. It parses an HTML <title> or <h1> and reports it as the service error. This is a catch-all for server-side errors that came back as HTML (Spring error page) or plain text instead of a valid PDF.
Source
Thrown at frontend/editor/src/core/hooks/tools/ocr/useOCROperation.ts:145
}
return [new File([blob], `ocr_${base}.zip`, { type: "application/zip" })];
}
// Not a PDF: surface error details if present
if (!head.startsWith("%PDF")) {
const textBuf = await blob.slice(0, 1024).arrayBuffer();
const text = new TextDecoder().decode(new Uint8Array(textBuf));
if (/error|exception|html/i.test(text)) {
if (text.includes("OCR tools") && text.includes("not installed")) {
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.",
);
}
const title =
text.match(/<title[^>]*>([^<]+)<\/title>/i)?.[1] ||
text.match(/<h1[^>]*>([^<]+)<\/h1>/i)?.[1] ||
"Unknown error";
throw new Error(`OCR service error: ${title}`);
}
throw new Error(`Response is not a valid PDF. Header: "${head}"`);
}
const originalName = originalFiles[0].name;
return [new File([blob], originalName, { type: "application/pdf" })];
};
// Static configuration object (without t function dependencies)
export const ocrOperationConfig = defineSingleFileTool({
validateParams: validateOCRParameters,
buildFormData: buildOCRFormData,
toApiParams: ocrToApiParams,
fromApiParams: ocrFromApiParams,
operationType: "ocr",
endpoint: ENDPOINT,
defaultParameters,
});View on GitHub (pinned to 9ef20dcab8)
Solutions
- Check backend logs around the time of the request for the matching exception/stack trace.
- Verify the request payload (file size, language param) is within the endpoint's limits; OCRmyPDF can fail on very large or corrupt PDFs.
- If the title is a proxy/gateway error (502/504), raise upstream timeouts for the OCR endpoint.
- Add server-side structured error responses (JSON) so the frontend can route by status code instead of scraping HTML.
Example fix
// before
const title = text.match(/<title[^>]*>([^<]+)<\/title>/i)?.[1] || text.match(/<h1[^>]*>([^<]+)<\/h1>/i)?.[1] || "Unknown error";
throw new Error(`OCR service error: ${title}`);
// after — include HTTP status context for diagnosis
throw new Error(`OCR service error: ${title} (HTTP ${response.status} from ${ENDPOINT})`); Defensive patterns
Strategy: try-catch
Validate before calling
// Treat non-2xx explicitly before parsing the body
if (response.status < 200 || response.status >= 300) {
// surface `OCR service error: HTTP ${response.status}` without scraping HTML
} Try / catch
try {
await runOcr();
} catch (e) {
if (e instanceof Error && e.message.startsWith("OCR service error:")) {
toast.error(e.message);
// surface backend logs hint to ops
} else throw e;
} Prevention
- Check backend logs for the matching exception when this surfaces.
- Verify OCR input size/params are within the endpoint's limits.
- Push the backend to return structured JSON errors so the frontend can route by status code.
When it happens
Trigger: Backend threw an exception (500) and Spring rendered its default error/whitelabel page; a reverse proxy (nginx, gateway) returned its own HTML error page; the OCR endpoint hit a size/time limit and returned an HTML error; a malformed request caused a 4xx with an HTML body.
Common situations: Transient backend crash during OCR; reverse-proxy timeout returning HTML; the OCRmyPDF subprocess crashed and the controller forwarded the stack trace as HTML.
Related errors
- Response is not a valid PDF. Header: "${head}"
- OCR tools (OCRmyPDF or Tesseract) are not installed on the s
- Missing stored file ID in response.
- ${operationName} operation failed: ${error.response?.data ||
- Sign up failed
AI-assisted analysis of Stirling-Tools/Stirling-PDF@9ef20dcab8 (2026-08-13).
Data as JSON: /api/errors/f0a8b658086344f9.
Report an issue: GitHub.