{"record":{"id":"502aa27ca0ddc4b1","repo":"gchq/CyberChef","slug":"this-operation-only-works-in-a-browser","errorCode":null,"errorMessage":"This operation only works in a browser","messagePattern":"This operation only works in a browser","errorType":"exception","errorClass":"OperationError","httpStatus":null,"severity":"error","filePath":"src/core/operations/OpticalCharacterRecognition.mjs","lineNumber":59,"sourceCode":"            },\n            {\n                name: \"OCR Engine Mode\",\n                type: \"option\",\n                value: OEM_MODES,\n                defaultIndex: 1\n            }\n        ];\n    }\n\n    /**\n     * @param {ArrayBuffer} input\n     * @param {Object[]} args\n     * @returns {string}\n     */\n    async run(input, args) {\n        const [showConfidence, oemChoice] = args;\n\n        if (!isWorkerEnvironment()) throw new OperationError(\"This operation only works in a browser\");\n\n        const type = isImage(input);\n        if (!type) {\n            throw new OperationError(\"Unsupported file type (supported: jpg,png,pbm,bmp) or no file provided\");\n        }\n\n        const assetDir = `${self.docURL}/assets/`;\n        const oem = OEM_MODES.indexOf(oemChoice);\n\n        try {\n            self.sendStatusMessage(\"Spinning up Tesseract worker...\");\n            const image = `data:${type};base64,${toBase64(input)}`;\n            const worker = await createWorker(\"eng\", oem, {\n                workerPath: `${assetDir}tesseract/worker.min.js`,\n                langPath: `${assetDir}tesseract/lang-data`,\n                corePath: `${assetDir}tesseract/tesseract-core.wasm.js`,\n                logger: progress => {\n                    if (isWorkerEnvironment()) {","sourceCodeStart":41,"sourceCodeEnd":77,"githubUrl":"https://github.com/gchq/CyberChef/blob/4290ea753912378913b1f3f54e0fc5720afeda5d/src/core/operations/OpticalCharacterRecognition.mjs#L41-L77","documentation":"Thrown by OpticalCharacterRecognition.run when isWorkerEnvironment() is false. OCR uses tesseract.js which spins up a Web Worker and references browser-only globals (self.docURL, self.sendStatusMessage), so it cannot run in the Node.js API / Node package build of CyberChef.","triggerScenarios":"run(input, args) invoked outside a Web Worker — e.g. via the Node REPL (npm run repl), the CyberChef Node library, or a server-side recipe. The check fires before any image validation.","commonSituations":"Using CyberChef as an npm dependency in a Node service; running recipes via the Node build that include OCR; scripting batch processing server-side; CI pipeline executing recipes headlessly.","solutions":["Run this operation in the browser UI or a worker context only.","For server-side OCR use tesseract.js directly (or another OCR library) outside CyberChef.","Remove the OCR step from Node-side recipes and perform OCR in a browser step."],"exampleFix":null,"handlingStrategy":"type-guard","validationCode":"import { isWorkerEnvironment } from \"core/Utils.mjs\";\nif (!isWorkerEnvironment()) {\n  // do not include OCR in Node-side recipes; run it in the browser\n}","typeGuard":"const canRunOCR = () => typeof self !== \"undefined\" && isWorkerEnvironment();","tryCatchPattern":null,"preventionTips":["Restrict OCR steps to browser/worker recipes.","For Node OCR, call tesseract.js directly instead of via CyberChef.","Gate the recipe branch on isWorkerEnvironment() before invoking."],"tags":["ocr","environment","browser-only","node"],"backgroundTag":null,"analyzedSha":"4290ea753912378913b1f3f54e0fc5720afeda5d","analyzedAt":"2026-08-13T06:05:50.210Z","schemaVersion":2},"datasetVersion":"2026-08-13T09:17:06.757Z"}