Budibase/budibase · error · ActiveContentFileError

File "${fileName}" contains active content which is not perm

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.

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)

Solutions

  1. Rename/convert to a safe format (SVG logo -> PNG, HTML report -> PDF)
  2. Zip the active-content files and upload the archive instead
  3. 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

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


AI-assisted analysis of Budibase/budibase@a81a902e9a (2026-08-29). Data as JSON: /api/errors/8d4a47ee4fb989f5. Report an issue: GitHub.