{"record":{"id":"a01c78dd09d4efb3","repo":"Budibase/budibase","slug":"unable-to-remove-top-level-directory-some-skelet","errorCode":null,"errorMessage":"Unable to remove top level directory - some skeleton files already exist.","messagePattern":"Unable to remove top level directory - some skeleton files already exist\\.","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"packages/cli/src/utils.ts","lineNumber":91,"sourceCode":"  return result\n}\n\nexport function progressBar(total: number) {\n  const bar = new progress.SingleBar({}, progress.Presets.shades_classic)\n  bar.start(total, 0)\n  return bar\n}\n\nexport function checkSlashesInUrl(url: string) {\n  return url.replace(/(https?:\\/\\/)|(\\/)+/g, \"$1$2\")\n}\n\nexport function moveDirectory(oldPath: string, newPath: string) {\n  const files = fs.readdirSync(oldPath)\n  // check any file exists already\n  for (let file of files) {\n    if (fs.existsSync(join(newPath, file))) {\n      throw new Error(\n        \"Unable to remove top level directory - some skeleton files already exist.\"\n      )\n    }\n  }\n  for (let file of files) {\n    fs.renameSync(join(oldPath, file), join(newPath, file))\n  }\n  fs.rmdirSync(oldPath)\n}\n\nexport function capitaliseFirstLetter(str: string) {\n  return str.charAt(0).toUpperCase() + str.slice(1)\n}\n\nexport function stringifyToDotEnv(json: Record<string, string | number>) {\n  let str = \"\"\n  for (let [key, value] of Object.entries(json)) {\n    str += `${key}=${value}\\n`","sourceCodeStart":73,"sourceCodeEnd":109,"githubUrl":"https://github.com/Budibase/budibase/blob/a81a902e9a8fe55b467d106765f6638f12e35c49/packages/cli/src/utils.ts#L73-L109","documentation":"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.","triggerScenarios":"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).","commonSituations":"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.","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"],"exampleFix":"// before\nmy-plugin/ package.json   (leftover from failed run)\n// Error: Unable to remove top level directory - some skeleton files already exist.\n// after\nrm -rf my-plugin && budibase-plugins init component my-plugin","handlingStrategy":"validation","validationCode":"import fs from \"fs\"\nimport { join } from \"path\"\nconst collisions = fs.readdirSync(tmpExtractDir).filter(f => fs.existsSync(join(targetDir, f)))\nif (collisions.length) throw new Error(`Conflicting files exist: ${collisions.join(\", \")}`)","typeGuard":null,"tryCatchPattern":"try {\n  initPlugin(targetDir)\n} catch (err) {\n  if ((err as Error).message.includes(\"already exist\")) {\n    // clean or empty the target directory and re-run init\n  } else throw err\n}","preventionTips":["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"],"tags":["cli","filesystem","conflict","init"],"backgroundTag":"file-already-exists","analyzedSha":"a81a902e9a8fe55b467d106765f6638f12e35c49","analyzedAt":"2026-08-29T01:03:10.972Z","schemaVersion":2},"datasetVersion":"2026-08-29T02:17:18.158Z"}