Budibase/budibase · error
Unable to remove top level directory - some skeleton files a
Error message
Unable to remove top level directory - some skeleton files already exist.
What it means
moveDirectory relocates the extracted skeleton contents from a temp directory to the target plugin directory. Before renaming, it checks that none of the top-level files already exist at the destination; any collision aborts with this error to avoid overwriting user files.
Source
Thrown at packages/cli/src/utils.ts:91
return result
}
export function progressBar(total: number) {
const bar = new progress.SingleBar({}, progress.Presets.shades_classic)
bar.start(total, 0)
return bar
}
export function checkSlashesInUrl(url: string) {
return url.replace(/(https?:\/\/)|(\/)+/g, "$1$2")
}
export function moveDirectory(oldPath: string, newPath: string) {
const files = fs.readdirSync(oldPath)
// check any file exists already
for (let file of files) {
if (fs.existsSync(join(newPath, file))) {
throw new Error(
"Unable to remove top level directory - some skeleton files already exist."
)
}
}
for (let file of files) {
fs.renameSync(join(oldPath, file), join(newPath, file))
}
fs.rmdirSync(oldPath)
}
export function capitaliseFirstLetter(str: string) {
return str.charAt(0).toUpperCase() + str.slice(1)
}
export function stringifyToDotEnv(json: Record<string, string | number>) {
let str = ""
for (let [key, value] of Object.entries(json)) {
str += `${key}=${value}\n`View on GitHub (pinned to a81a902e9a)
Solutions
- Remove or move aside the conflicting files listed by `ls` in the target directory, then re-run
- Delete the partial plugin directory and run init again in a clean folder
- Initialize into a new empty directory instead of an existing one
Example fix
// before my-plugin/ package.json (leftover from failed run) // Error: Unable to remove top level directory - some skeleton files already exist. // after rm -rf my-plugin && budibase-plugins init component my-plugin
Defensive patterns
Strategy: validation
Validate before calling
import fs from "fs"
import { join } from "path"
const collisions = fs.readdirSync(tmpExtractDir).filter(f => fs.existsSync(join(targetDir, f)))
if (collisions.length) throw new Error(`Conflicting files exist: ${collisions.join(", ")}`) Try / catch
try {
initPlugin(targetDir)
} catch (err) {
if ((err as Error).message.includes("already exist")) {
// clean or empty the target directory and re-run init
} else throw err
} Prevention
- Always initialize plugins into an empty, fresh directory
- After a failed init, remove partial output before retrying
- Don't reuse an existing project folder for scaffolding
When it happens
Trigger: Running the init/skeleton command into a directory where at least one file with the same name as a skeleton top-level file already exists (fs.existsSync(join(newPath, file)) is true for any file).
Common situations: Re-running init in a partially created plugin after a previous failed run; initializing into a non-empty existing folder; leftover files from a crashed move; a stale package.json already present.
Related errors
- Please run in a plugin directory - must contain package.json
- Please run in a plugin directory - must contain schema.json
- Unable to bulk remove documents: ${res.error}
- Unable to access MinIO/S3 - check environment config.
- Replication failed - ${JSON.stringify(err)}
AI-assisted analysis of Budibase/budibase@a81a902e9a (2026-08-29).
Data as JSON: /api/errors/a01c78dd09d4efb3.
Report an issue: GitHub.