Budibase/budibase · error · HTTPError

Project package contains paths that are too deep.

Error message

Project package contains paths that are too deep.

What it means

During package import, each file's relative path is split on slashes and compared against MAX_PATH_SEGMENTS. Deeper nesting than allowed is rejected with this 400 HTTPError to bound resource usage and avoid filesystem limits. It fires after the safety check and before symlink handling in readDirectoryRecursively.

Source

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

  )
}

const readDirectoryRecursively = async (
  dirPath: string,
  rootPath = dirPath,
  totals = { files: 0, bytes: 0 }
): Promise<string[]> => {
  const entries = await fsp.readdir(dirPath, { withFileTypes: true })
  const files: string[] = []

  for (const entry of entries) {
    const fullPath = join(dirPath, entry.name)
    const relPath = relative(rootPath, fullPath)
    if (!isSafeArchivePath(relPath)) {
      throw new HTTPError("Project package contains unsafe paths.", 400)
    }
    if (relPath.split(/[\\/]/).length > MAX_PATH_SEGMENTS) {
      throw new HTTPError(
        "Project package contains paths that are too deep.",
        400
      )
    }
    if (entry.isSymbolicLink()) {
      throw new HTTPError("Project package contains unsupported links.", 400)
    }
    if (entry.isDirectory()) {
      files.push(
        ...(await readDirectoryRecursively(fullPath, rootPath, totals))
      )
    } else {
      const stats = await fsp.stat(fullPath)
      totals.files += 1
      totals.bytes += stats.size
      if (totals.files > MAX_PACKAGE_FILES) {
        throw new HTTPError("Project package contains too many files.", 400)
      }

View on GitHub (pinned to a81a902e9a)

Solutions

  1. Flatten the package structure so files sit within the allowed depth before archiving
  2. Exclude generated directories (node_modules, build output) from the package
  3. Check the source app for unusually deep resource naming and simplify
  4. If legitimately needed, raise MAX_PATH_SEGMENTS in a fork — not recommended

Example fix

// before
// package contains: files/a/b/c/d/e/f/g/h/deep.json (9+ segments)
// after
// restructure to: files/generated/deep.json (within MAX_PATH_SEGMENTS)
Defensive patterns

Strategy: validation

Validate before calling

const segments = relPath.split(/[\\/]/).length
if (segments > MAX_PATH_SEGMENTS) throw new Error(`Path too deep (${segments} segments): ${relPath}`)

Type guard

null

Try / catch

try {
  await importProject(packagePath)
} catch (e) {
  if (e instanceof HTTPError && e.message.includes("too deep")) {
    // flatten package structure or exclude deep generated trees, then re-import
  } else throw e
}

Prevention

When it happens

Trigger: Importing a project package that contains files nested more than MAX_PATH_SEGMENTS directories deep — e.g. node_modules-style trees, generated code bundles, or archives that embed several directory layers inside the package.

Common situations: Zipping an entire app folder including dependency/build output; automating exports that capture extra nested directories; malicious archives engineered to be pathologically deep.

Related errors


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