{"record":{"id":"8e222a1f6e09b8a7","repo":"HeyPuter/puter","slug":"unauthorized-8e222a","errorCode":"unauthorized","errorMessage":"Authentication required","messagePattern":"Authentication required","errorType":"http","errorClass":"HttpError","httpStatus":401,"severity":"error","filePath":"src/backend/drivers/ai-ocr/OCRDriver.ts","lineNumber":182,"sourceCode":"                    '[OCRDriver] Failed to init Mistral:',\n                    (e as Error).message,\n                );\n            }\n        }\n    }\n\n    async recognize(args: RecognizeArgs) {\n        if (args.test_mode) return sampleResponse();\n\n        const provider = this.#resolveProvider(args);\n        if (!provider)\n            throw new HttpError(500, 'No OCR provider configured', {\n                legacyCode: 'internal_error',\n            });\n\n        const actor = Context.get('actor');\n        if (!actor)\n            throw new HttpError(401, 'Authentication required', {\n                legacyCode: 'unauthorized',\n            });\n\n        const input = args.source ?? args.file;\n        if (!input)\n            throw new HttpError(400, '`source` is required', {\n                legacyCode: 'bad_request',\n            });\n\n        const loaded = await loadFileInput(\n            this.stores,\n            this.services.fs,\n            actor,\n            input,\n            { acceptWebInput: true },\n        );\n\n        if (provider === 'aws-textract') {","sourceCodeStart":164,"sourceCodeEnd":200,"githubUrl":"https://github.com/HeyPuter/puter/blob/908ec23eda38526170322c3edf71ba45ecb1ca95/src/backend/drivers/ai-ocr/OCRDriver.ts#L164-L200","documentation":"The OCR driver requires an authenticated actor in the request-scoped Context (AsyncLocalStorage). Context.get('actor') returned null, meaning the request did not pass through authentication middleware or the middleware did not populate the actor. The OCR endpoint requires authentication because it accesses user credits and metering.","triggerScenarios":"Calling the OCR recognize() method without authentication; the route's auth gate is misconfigured; calling recognize() outside an HTTP request context (e.g. in a test or background job) without setting up Context.","commonSituations":"The OCR API route is missing the authentication middleware in its RouteOptions; testing the driver directly without mocking Context; a middleware ordering bug causes the actor to not be set before the driver runs.","solutions":["Ensure the client passes a valid authentication token (API key or session) with the OCR request.","Verify the OCR route/controller has the auth gate set in RouteOptions.","In tests, set Context.set('actor', mockActor) before calling recognize()."],"exampleFix":"// before — calling OCR without auth (client side)\nconst result = await puter.ai.ocr({ url: 'doc.pdf' });\n\n// after — ensure authentication is established\nawait puter.auth.signIn(); // or ensure API token is set\nconst result = await puter.ai.ocr({ url: 'doc.pdf' });","handlingStrategy":"validation","validationCode":"import { Context } from '../../core/context.js';\n// Before calling recognize(), verify authentication\nconst actor = Context.get('actor');\nif (!actor) {\n  throw new Error('Authentication required');\n}\nconst result = await driver.recognize(args);","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Ensure the client SDK is authenticated (puter.auth.signIn() or API token) before calling OCR.","Verify the OCR route has auth middleware in its RouteOptions.","In tests, mock Context with an actor before calling recognize()."],"tags":["ocr","authentication","context","als","actor","unauthorized"],"backgroundTag":null,"analyzedSha":"908ec23eda38526170322c3edf71ba45ecb1ca95","analyzedAt":"2026-08-12T20:53:15.911Z","schemaVersion":2},"datasetVersion":"2026-08-12T23:17:12.415Z"}