HeyPuter/puter · error · HttpError

unauthorized

unauthorized

Error message

actor not found in context

What it means

CloudflareImageProvider.generate reads Context.get('actor'); if absent it throws HTTP 401 unauthorized ('actor not found in context'). Like the driver-level auth check, this means the call isn't running inside an authenticated request lifecycle.

Source

Thrown at src/backend/drivers/ai-image/providers/cloudflare/CloudflareImageProvider.ts:104

    async generate(params: IGenerateParams): Promise<string> {
        const options = params as CloudflareGenerateParams;
        const { prompt, test_mode } = options;
        const ratio = this.#normalizeRatio(options.ratio);
        const selectedModel = this.#getModel(options.model);

        if (test_mode) {
            return 'https://puter-sample-data.puter.site/image_example.png';
        }

        if (typeof prompt !== 'string' || prompt.trim().length === 0) {
            throw new HttpError(400, '`prompt` must be a non-empty string', {
                legacyCode: 'bad_request',
            });
        }

        const actor = Context.get('actor');
        if (!actor) {
            throw new HttpError(401, 'actor not found in context', {
                legacyCode: 'unauthorized',
            });
        }

        // Canonical `input_images`/`input_image` → Cloudflare's `image` field.
        // Cloudflare accepts a single input image; a URL is fetched to base64
        // server-side (SSRF-guarded) since the API has no URL field.
        const singleInput = resolveSingleInputImage(options, 'Cloudflare');
        if (singleInput) {
            options.image ??= isHttpUrl(singleInput)
                ? (await fetchImageAsBase64(singleInput)).base64
                : singleInput;
        }

        const steps = this.#resolveSteps(selectedModel, options);
        const costComponents = this.#estimateCost(selectedModel, ratio, steps, {
            hasInputImage:
                typeof options.image === 'string' &&

View on GitHub (pinned to 908ec23eda)

Solutions

  1. Reach the provider through the authed image-generation driver/route so actor is set.
  2. If invoking directly, set Context actor first (Context.run({ actor }, ...)).
  3. In tests, authenticate a user via setupPuterTestEnv() before calling generate().

Example fix

// before — provider called with no actor
await cfProvider.generate({ prompt });
// after — run inside an authed context
await Context.run({ actor }, () => cfProvider.generate({ prompt }));
Defensive patterns

Strategy: validation

Validate before calling

const actor = Context.get('actor');
if (!actor) throw new Error('CloudflareImageProvider.generate requires an authed actor');

Type guard

function hasActor(ctx) {
  const a = ctx.get('actor');
  return !!a && typeof a === 'object';
}

Prevention

When it happens

Trigger: Calling CloudflareImageProvider.generate directly outside an authed request, or a code path that reaches it without the auth gate having set Context actor.

Common situations: Direct provider invocation in tests/scripts; a route missing the auth gate; an internal job invoking the provider without setting actor.

Related errors


AI-assisted analysis of HeyPuter/puter@908ec23eda (2026-08-12). Data as JSON: /api/errors/1d323dba97e9b2c9. Report an issue: GitHub.