{"record":{"id":"25d7eba487df5320","repo":"HeyPuter/puter","slug":"unauthorized-25d7eb","errorCode":"unauthorized","errorMessage":"actor not found in context","messagePattern":"actor not found in context","errorType":"http","errorClass":"HttpError","httpStatus":401,"severity":"error","filePath":"src/backend/drivers/ai-image/providers/together/TogetherImageProvider.ts","lineNumber":107,"sourceCode":"        }\n\n        // Canonical `input_images` → Together's native fields. Together accepts\n        // a single input image: a URL goes to `image_url`, base64/data-URI to\n        // `image_base64` (via the existing `input_image` alias).\n        const singleInput = resolveSingleInputImage(params, 'Together AI');\n        if (singleInput) {\n            if (isHttpUrl(singleInput)) {\n                options.image_url ??= singleInput;\n            } else {\n                options.input_image ??= singleInput;\n            }\n        }\n\n        ratio = ratio || TOGETHER_DEFAULT_RATIO;\n\n        const actor = Context.get('actor');\n        if (!actor) {\n            throw new HttpError(401, 'actor not found in context', {\n                legacyCode: 'unauthorized',\n            });\n        }\n\n        const pricingUnit = selectedModel.pricing_unit ?? 'per-MP';\n\n        let costInMicroCents: number;\n        let usageAmount: number;\n        let usageKey: string;\n\n        if (pricingUnit === 'per-image') {\n            const centsPerImage = selectedModel.costs['per-image'];\n            if (centsPerImage === undefined) {\n                throw new Error(\n                    `Model ${selectedModel.id} missing 'per-image' cost`,\n                );\n            }\n            costInMicroCents = centsPerImage * 1_000_000;","sourceCodeStart":89,"sourceCodeEnd":125,"githubUrl":"https://github.com/HeyPuter/puter/blob/908ec23eda38526170322c3edf71ba45ecb1ca95/src/backend/drivers/ai-image/providers/together/TogetherImageProvider.ts#L89-L125","documentation":"The Together image provider retrieves the authenticated actor from the request-scoped Context (AsyncLocalStorage) via Context.get('actor'). If no actor is set in the context, it means the request did not pass through proper authentication middleware, or the middleware failed to populate the actor. This should not happen in normal request flow — it indicates a misconfigured route or middleware chain.","triggerScenarios":"The generate() method is called outside an HTTP request context (e.g. in a background job or test) where the ALS context has no actor set. Or the route handling image generation is missing the authentication middleware. Or Context.get('actor') is called after the ALS context has been lost (e.g. in a detached promise).","commonSituations":"Calling the provider directly in a unit test without setting up Context; a route definition in the controller layer is missing the auth gate in RouteOptions; the actor was set but the ALS context was not propagated into an async callback.","solutions":["Ensure the controller route that invokes this provider has the authentication gate set in its RouteOptions.","If calling outside a request (tests, scripts), set Context.set('actor', mockActor) before calling generate().","Verify that async operations after Context.get do not lose the ALS scope — avoid fire-and-forget detached promises."],"exampleFix":"// before — calling generate() in a test without context\nconst url = await provider.generate({ prompt: 'a cat' });\n\n// after — set up the actor in context first\nimport { Context } from '../../../../core/context.js';\nContext.set('actor', mockActor);\nconst url = await provider.generate({ prompt: 'a cat' });","handlingStrategy":"validation","validationCode":"import { Context } from '../../../../core/context.js';\n// Before calling generate(), verify the actor is present\nconst actor = Context.get('actor');\nif (!actor) {\n  throw new Error('Authentication required — no actor in request context');\n}\nconst url = await provider.generate(params);","typeGuard":null,"tryCatchPattern":null,"preventionTips":["In tests, always set Context.set('actor', mockActor) before calling provider methods.","Ensure controller routes have the auth gate in RouteOptions.","Avoid calling provider methods from detached promises that lose the ALS context."],"tags":["together","authentication","context","als","actor"],"backgroundTag":null,"analyzedSha":"908ec23eda38526170322c3edf71ba45ecb1ca95","analyzedAt":"2026-08-12T20:53:15.911Z","schemaVersion":2},"datasetVersion":"2026-08-12T23:17:12.415Z"}