Budibase/budibase · error · Error

Cannot import a non-text based file.

Error message

Cannot import a non-text based file.

What it means

getTemplateStream rejects uploaded template files whose MIME type is not text/plain, because app template imports are text-based DB dumps (dump.txt), not binary archives. Any binary upload passed as `template.file` is rejected before a read stream is opened.

Source

Thrown at packages/server/src/sdk/workspace/backups/imports.ts:135

      automation.definition.trigger.inputs = {
        schemaUrl: old.schemaUrl.replace(oldDevAppId, devId),
        triggerUrl: old.triggerUrl.replace(oldProdAppId, prodAppId),
      }
    }
    automation.appId = devId
    toSave.push(automation)
  }
  await db.bulkDocs(toSave)
}

/**
 * This function manages temporary template files which are stored by Koa.
 * @param template The template object retrieved from the Koa context object.
 * @returns Returns a fs read stream which can be loaded into the database.
 */
async function getTemplateStream(template: TemplateType) {
  if (template.file && template.file.type !== "text/plain") {
    throw new Error("Cannot import a non-text based file.")
  }
  if (template.file) {
    return fs.createReadStream(template.file.path)
  } else if (template.key) {
    const [type, name] = template.key.split("/")
    const tmpPath = await downloadTemplate(type, name)
    return fs.createReadStream(join(tmpPath, name, "db", "dump.txt"))
  } else {
    throw new Error("Either file or key is required.")
  }
}

export async function untarFile(file: { path: string }) {
  const tmpPath = join(budibaseTempDir(), uuid())
  await fsp.mkdir(tmpPath)
  // extract the tarball
  await tar.extract({
    cwd: tmpPath,

View on GitHub (pinned to a81a902e9a)

Solutions

  1. Upload a plain-text export (dump.txt style) rather than a binary archive
  2. Set the correct file MIME type (text/plain) when uploading, e.g. ensure the multipart part declares it
  3. Use the app import endpoint that accepts tar/zip exports instead of the template import path
  4. Re-export the app using the export feature that produces the text-based DB dump

Example fix

// before
curl -F "file=@export.tar.gz;type=application/zip" /api/apps/import  // throws
// after
curl -F "file=@dump.txt;type=text/plain" /api/templates/import
Defensive patterns

Strategy: validation

Validate before calling

if (template.file && template.file.type !== "text/plain") {
  throw new Error("Expected a text/plain export file")
}

Type guard

function isTextFile(f: { type?: string } | undefined): f is { type: "text/plain" } {
  return !!f && f.type === "text/plain"
}

Try / catch

try {
  await importApp(template)
} catch (err: any) {
  if (err.message.includes("non-text based file")) {
    // request a text-based export instead
  } else {
    throw err
  }
}

Prevention

When it happens

Trigger: importApp called with a template.file whose `type` is e.g. application/zip, application/octet-stream, or an empty/missing type — typically uploading a binary export archive directly instead of a plain-text export, or a client sending the file without the correct content type.

Common situations: Uploading a .tar.gz export into an import endpoint expecting a text dump; curl uploads missing -F type annotations so the browser/koa reports octet-stream; mixing up the import endpoints that accept encrypted/binary packages vs text templates.

Related errors


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