{"record":{"id":"880bca3f22fbef16","repo":"HeyPuter/puter","slug":"authentication-required","errorCode":null,"errorMessage":"Authentication required","messagePattern":"Authentication required","errorType":"http","errorClass":"HttpError","httpStatus":401,"severity":"warning","filePath":"extensions/appTelemetry.ts","lineNumber":137,"sourceCode":"            min: 0,\n            max: MAX_OFFSET,\n            fallback: 0,\n        });\n\n        const app = await this.stores.app.getByUid(app_uuid);\n        if (!app) throw new HttpError(404, 'App not found');\n\n        // The `apps-of-user:<uuid>:write` implicator keys on the owner's\n        // UUID, not the numeric id. Look up the owner explicitly — the raw\n        // app row only carries `owner_user_id`. (v1 got the owner for free\n        // because its entity-storage layer eager-joined the owner row.)\n        const ownerId = (app as { owner_user_id?: number }).owner_user_id;\n        if (!ownerId) throw new HttpError(404, 'App owner not found');\n        const owner = await this.stores.user.getById(ownerId);\n        if (!owner?.uuid) throw new HttpError(404, 'App owner not found');\n\n        const actor = Context.get('actor');\n        if (!actor) throw new HttpError(401, 'Authentication required');\n        const ownsApp = await this.services.permission\n            .check(actor as Actor, `apps-of-user:${owner.uuid}:write`)\n            .catch(() => false);\n        if (!ownsApp) throw new HttpError(403, 'Permission denied');\n\n        const appId = (app as { id: number }).id;\n\n        const users = (await this.clients.db.read(\n            `SELECT u.id, u.username, u.uuid, u.email FROM user_to_app_permissions p\n             INNER JOIN ${this.clients.db.quoteIdentifier('user')} u ON p.user_id = u.id\n             WHERE p.permission = 'flag:app-is-authenticated' AND p.app_id = ?\n             ORDER BY (p.dt IS NOT NULL), p.dt, p.user_id\n             LIMIT ? OFFSET ?`,\n            [appId, safeLimit, safeOffset],\n        )) as Array<{\n            id: number;\n            username: string;\n            uuid: string;","sourceCodeStart":119,"sourceCodeEnd":155,"githubUrl":"https://github.com/HeyPuter/puter/blob/908ec23eda38526170322c3edf71ba45ecb1ca95/extensions/appTelemetry.ts#L119-L155","documentation":"Gemini completed the operation but the response carried raiMediaFilteredCount > 0 and zero generatedVideos — Google's Responsible AI filter rejected the output. The driver surfaces this as 400 disallowed_value (not 500) because it is a client/content problem, not an outage. The reasons come from raiMediaFilteredReasons, falling back to 'content policy'.","triggerScenarios":"Submitting a prompt (or reference image / last-frame) whose content triggers Gemini's RAI filter — violence, sexual content, public figures, disallowed topics. The job reaches 'complete' but every candidate was filtered.","commonSituations":"Prompt with policy-sensitive wording; reference image flagged by the vision safety model; locale/account under stricter policy tier; prompt that was fine at low safety but blocked at the model's configured safety threshold.","solutions":["Rephrase the prompt to remove policy-sensitive terms; re-read the reasons string in the error message.","If using reference_images / last_frame, replace or re-crop the flagged input asset.","Offer the user an edit step before retry rather than auto-retrying the same payload.","Track which prompts filter repeatedly and surface a UI hint to revise them."],"exampleFix":"// before\nconst url = await puter.ai.txt2video({ prompt: userPrompt, model: 'gemini-2.5-video' });\n\n// after — catch the filter and let the user revise\ntry {\n  const url = await puter.ai.txt2video({ prompt: userPrompt, model: 'gemini-2.5-video' });\n} catch (e) {\n  if (e?.code === 'disallowed_value') {\n    showUser('The provider rejected this prompt. Please rephrase it.');\n    return;\n  }\n  throw e;\n}","handlingStrategy":"try-catch","validationCode":null,"typeGuard":null,"tryCatchPattern":"try { return await puter.ai.txt2video(params); }\ncatch (e) {\n  if (e?.code === 'disallowed_value') {\n    notifyUser(`Provider blocked this prompt (${e.message}). Please revise it.`);\n    return null;\n  }\n  throw e;\n}","preventionTips":["Avoid prompts with policy-sensitive subjects when targeting Gemini video.","Show the provider's reasons string (e.message) to the user so they can revise.","Do not auto-retry the identical payload after a filter — it will filter again."],"tags":["ai-video","gemini","content-filter","moderation"],"backgroundTag":null,"analyzedSha":"908ec23eda38526170322c3edf71ba45ecb1ca95","analyzedAt":"2026-08-12T20:53:15.911Z","schemaVersion":2},"datasetVersion":"2026-08-12T23:17:12.415Z"}