Budibase/budibase · error · ActiveContentFileError
File " " contains active content which is not permitted
Error message
File "${fileName}" contains active content which is not permitted What it means
Thrown as ActiveContentFileError by uploadFile when the file's extension is in ACTIVE_CONTENT_EXTENSIONS (html, htm, js, mjs, svg, wasm, xhtml, etc.). These types can execute scripts when served, enabling stored XSS, so they are rejected regardless of role or environment.
Solutions
- Rename/convert to a safe format (SVG logo -> PNG, HTML report -> PDF)
- Zip the active-content files and upload the archive instead
- Serve the active content from a dedicated static host/CDN outside Budibase
Example fix
// before upload 'logo.svg' as attachment // after export and upload 'logo.png'
Defensive patterns
Strategy: validation
Validate before calling
const ACTIVE = new Set(['html','htm','js','jse','mjs','svg','svgz','wasm','xhtml','mhtml','shtml'])
function isNotActiveContent(name) {
return !ACTIVE.has((name.split('.').pop() || '').toLowerCase())
} Type guard
const isActiveContentFile = (name: string): boolean =>
['html','htm','js','jse','mjs','svg','svgz','wasm','xhtml','mhtml','shtml'].includes((name.split('.').pop() || '').toLowerCase()) Try / catch
try {
await api.uploadFile(fd)
} catch (err) {
if (err instanceof ActiveContentFileError) {
// convert to a safe format (PNG/PDF) and retry
} else throw err
} Prevention
- Convert SVG to PNG and HTML to PDF before attaching
- Never attempt to host executable web assets (js/wasm/html) as attachments
- Run the client-side extension check for the ACTIVE_CONTENT_EXTENSIONS list before every upload
When it happens
Trigger: Uploading any file whose extension is html/js/svg/wasm and similar active content types to the attachment upload endpoint.
Common situations: Teams trying to attach HTML reports, SVG logos, or JS bundles as app attachments; hosting a static site's assets inside Budibase attachments.
Related errors
- File " " has an invalid extension
- File " " has no extension, an extension is required to…
- Attempted to upload a file without a filename
- Attempted to upload a file without a path
- Cannot reset password.
AI-assisted analysis of Budibase/budibase@a81a902e9a (2026-08-29).
Data as JSON: /api/errors/8d4a47ee4fb989f5.
Report an issue: GitHub.
Appendix: source
Thrown at packages/server/src/api/controllers/static/index.ts:294
)
}
const extensionLower = extension.toLowerCase()
const isPublicUser =
ctx.roleId === roles.BUILTIN_ROLE_IDS.PUBLIC ||
ctx.user?.roleId === roles.BUILTIN_ROLE_IDS.PUBLIC
const enforceInvalidExtension = isPublicUser || !env.SELF_HOSTED
if (
enforceInvalidExtension &&
InvalidFileExtensions.includes(extensionLower)
) {
throw new BadRequestError(
`File "${fileName}" has an invalid extension: "${extension}"`
)
}
if (ACTIVE_CONTENT_EXTENSIONS.has(extensionLower)) {
throw new ActiveContentFileError(fileName)
}
const mimeType =
typeof rawMimeType === "string" ? rawMimeType.toLowerCase() : undefined
if (
mimeType &&
ACTIVE_CONTENT_MIME_TYPES.some(type => mimeType.includes(type))
) {
throw new ActiveContentFileError(fileName)
}
if (
filePath &&
(typeof filePath === "string" || Buffer.isBuffer(filePath)) &&
(await detectActiveContent(filePath))
) {
throw new ActiveContentFileError(fileName)
}View on GitHub (pinned to a81a902e9a)