{"record":{"id":"f00f1b7366f165d3","repo":"quasarframework/quasar","slug":"refusing-to-remove-the-project-root-as-build-outpu","errorCode":null,"errorMessage":"Refusing to remove the project root as build output","messagePattern":"Refusing to remove the project root as build output","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"critical","filePath":"app-vite/lib/utils/remove-build-artifacts.js","lineNumber":82,"sourceCode":"\n  const project = resolve(projectDir)\n  const effectiveProject = fse.realpathSync(project)\n  const home = fse.realpathSync(resolve(homedir()))\n  const target = resolve(projectDir, targetDir)\n  const effectiveTarget = getEffectivePath(target)\n\n  if (isFilesystemRoot(target) || isFilesystemRoot(effectiveTarget)) {\n    throw new Error('Refusing to remove a filesystem root as build output')\n  }\n\n  if (target === home || effectiveTarget === home) {\n    throw new Error(\n      'Refusing to remove the user home directory as build output'\n    )\n  }\n\n  if (target === project || effectiveTarget === effectiveProject) {\n    throw new Error('Refusing to remove the project root as build output')\n  }\n\n  if (\n    allowOutsideProject !== true &&\n    isContainedPath(effectiveProject, effectiveTarget) === false\n  ) {\n    throw new Error(\n      'Build output directory must remain inside the project. Set build.allowOutsideProjectDistDir to true to explicitly allow an external directory.'\n    )\n  }\n\n  return { target, effectiveTarget }\n}\n\nexport function removeBuildArtifacts(options) {\n  const { target, effectiveTarget } = getBuildArtifactsCleanTarget(options)\n\n  if (fse.pathExistsSync(target) === false) return","sourceCodeStart":64,"sourceCodeEnd":100,"githubUrl":"https://github.com/quasarframework/quasar/blob/4841521b5f635a971eb9e2710e5542efd194691b/app-vite/lib/utils/remove-build-artifacts.js#L64-L100","documentation":"getBuildArtifactsCleanTarget refuses to delete the project root itself as build output. If the resolved target equals the project directory, or its realpath equals the project's realpath, removal would wipe the whole project and is blocked.","triggerScenarios":"Setting the build output directory to '.' or the projectDir itself (e.g. distDir: '.', or targetDir: projectDir in programmatic use), so resolve(projectDir, targetDir) === project.","commonSituations":"distDir: '.' in quasar.config.js; confusing projectDir/targetDir parameters in a custom script; empty string or './' collapsing to the project root after resolution.","solutions":["Set distDir to a dedicated subdirectory like 'dist'","If you intended './dist', note '.' alone resolves to the project root — use 'dist'","In scripts, assert target !== projectDir before invoking the cleaner"],"exampleFix":"// before\ndistDir: '.'\n// after\ndistDir: 'dist'","handlingStrategy":"validation","validationCode":"const path = require('node:path')\nconst projectDir = path.resolve(process.cwd())\nconst target = path.resolve(projectDir, distDir)\nif (target === projectDir) throw new Error('dist dir equals project root; use a subdirectory like dist')","typeGuard":null,"tryCatchPattern":"try {\n  await removeBuildArtifacts(opts)\n} catch (err) {\n  if (err.message === 'Refusing to remove the project root as build output') {\n    // fix distDir (use 'dist'), never override\n  } else throw err\n}","preventionTips":["Use a dedicated subdirectory ('dist') for build output, never '.'","Keep targetDir and projectDir parameters distinct in custom scripts","Compare resolved paths before any rm -rf style operation in your own tooling"],"tags":["safety","filesystem","config"],"backgroundTag":"unsafe-delete-path","analyzedSha":"4841521b5f635a971eb9e2710e5542efd194691b","analyzedAt":"2026-08-30T01:13:14.944Z","schemaVersion":2},"datasetVersion":"2026-08-30T03:17:51.788Z"}