Budibase/budibase · error · Error

Either file or key is required.

Error message

Either file or key is required.

What it means

getTemplateStream requires the template to supply either an uploaded `file` or an object-store `key`; when both are absent it has nothing to stream from and throws. It is the terminal else of the file/key branch in importApp's stream resolution.

Source

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

}

/**
 * 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,
    file: file.path,
  })
  return tmpPath
}

export async function decryptFiles(path: string, password: string) {
  try {
    const processDirectory = async (dirPath: string) => {
      for (let file of await fsp.readdir(dirPath)) {

View on GitHub (pinned to a81a902e9a)

Solutions

  1. Attach the export file to the multipart request under the expected field name
  2. Supply template.key pointing to a valid object-store template (type/name)
  3. Validate the request body client-side before calling importApp
  4. Check the downloadTemplate path if relying on key — ensure the template exists in the store

Example fix

// before
await importApp({ name: "my-app" } as any) // throws
// after
await importApp({ name: "my-app", file: { path: tmpDumpPath, type: "text/plain", password: "" } })
Defensive patterns

Strategy: validation

Validate before calling

if (!template.file && !template.key) {
  throw new Error("Provide either template.file or template.key")
}

Type guard

function hasImportSource<T extends { file?: unknown; key?: string }>(t: T): t is T & ({ file: object } | { key: string }) {
  return !!t.file || !!t.key
}

Try / catch

try {
  await importApp(template)
} catch (err: any) {
  if (err.message.includes("file or key is required")) {
    // attach the export payload and retry
  } else {
    throw err
  }
}

Prevention

When it happens

Trigger: importApp called with a template object containing neither template.file nor template.key — e.g. multipart upload missing the file field, or a programmatic import constructing { name } only.

Common situations: API clients forgetting the file form field in multipart requests; templates referencing an object-store key that was never uploaded and code paths that strip the key; scripts importing apps without attaching the export payload.

Understand the failure class

Background: Missing required parameter errors: what 'X is required' and 'the required X param is missing' mean, and how to fix them — this error's family across 27 libraries.

Related errors


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