{"record":{"id":"4339762a09b37b1d","repo":"HeyPuter/puter","slug":"unauthorized-433976","errorCode":"unauthorized","errorMessage":"Authentication required","messagePattern":"Authentication required","errorType":"http","errorClass":"HttpError","httpStatus":401,"severity":"error","filePath":"src/backend/drivers/ai-image/ImageGenerationDriver.ts","lineNumber":124,"sourceCode":"                    (model as { costs?: Record<string, number> }).costs ?? {},\n                )) {\n                    if (typeof raw !== 'number' || !Number.isFinite(raw))\n                        continue;\n                    out.push({\n                        usageType: `${model.provider}:${model.id}:${costKey}`,\n                        costValue: raw,\n                        source: `driver:aiImage/${model.provider}`,\n                    });\n                }\n            }\n        }\n        return out;\n    }\n\n    async generate(args: IGenerateParams): Promise<string> {\n        const actor = Context.get('actor') as Actor | undefined;\n        if (!actor)\n            throw new HttpError(401, 'Authentication required', {\n                legacyCode: 'unauthorized',\n            });\n\n        const puterOutputPath = args.puter_output_path;\n        delete args.puter_output_path;\n\n        // Validate the output path early — before spending credits.\n        let resolvedOutputPath: string | undefined;\n        if (puterOutputPath) {\n            const username = actor.user?.username;\n            const userId = actor.user?.id;\n            if (!userId || !username) {\n                throw new HttpError(\n                    400,\n                    'User ID required for puter_output_path',\n                    { legacyCode: 'bad_request' },\n                );\n            }","sourceCodeStart":106,"sourceCodeEnd":142,"githubUrl":"https://github.com/HeyPuter/puter/blob/908ec23eda38526170322c3edf71ba45ecb1ca95/src/backend/drivers/ai-image/ImageGenerationDriver.ts#L106-L142","documentation":"ImageGenerationDriver.generate() reads Context.get('actor') at the top of the call; if no actor is present it throws HTTP 401. This means the request never passed through Puter's authentication middleware, so there is no authenticated user to bill, attribute, or permission against.","triggerScenarios":"Calling the image-generation driver from a context where auth was skipped — a misconfigured route/driver endpoint missing the auth gate, a background/internal invocation that forgot to set Context actor, or calling generate() directly in tests without a logged-in actor.","commonSituations":"New driver route registered without the auth RouteOptions gate; a test harness that calls the driver directly; an internal job that invokes the driver outside a request lifecycle.","solutions":["Ensure the route/driver endpoint declaring puter-image-generation carries the authentication gate (RouteOptions auth) so actor is populated.","If invoking generate() programmatically, set Context actor first (or run inside an authenticated request).","In tests, use setupPuterTestEnv() and authenticate a user before calling generate()."],"exampleFix":"// before — driver called with no auth context\nawait imageDriver.generate({ prompt: 'cat' });\n// after — ensure auth sets the actor\n// route-level: register the endpoint with the auth gate\nextension.post('/drivers/call', { auth: true }, handler);\n// or in tests:\nconst actor = await getTestUserActor();\nawait Context.run({ actor }, () => imageDriver.generate({ prompt: 'cat' }));","handlingStrategy":"validation","validationCode":"// Ensure the call runs inside an authenticated request.\nconst actor = Context.get('actor');\nif (!actor) throw new Error('generate() must run with an authenticated actor');\nawait driver.generate(args);","typeGuard":"function hasActor(ctx) {\n  const a = ctx.get('actor');\n  return !!a && typeof a === 'object';\n}","tryCatchPattern":null,"preventionTips":["Register image-generation endpoints with the auth gate so actor is populated.","Never call generate() outside an authenticated request lifecycle.","In tests, authenticate a user (setupPuterTestEnv) before invoking the driver."],"tags":["ai-image","authentication","actor","unauthorized"],"backgroundTag":null,"analyzedSha":"908ec23eda38526170322c3edf71ba45ecb1ca95","analyzedAt":"2026-08-12T20:53:15.911Z","schemaVersion":2},"datasetVersion":"2026-08-12T23:17:12.415Z"}