quasarframework/quasar · critical · Error
Refusing to remove a filesystem root as build output
Error message
Refusing to remove a filesystem root as build output
What it means
As a destructive-operation guard, getBuildArtifactsCleanTarget refuses to treat a filesystem root ('/' on POSIX, drive root on Windows) as build output. It compares both the raw resolved target and its realpath-resolved effective path (catching symlinks that point at a root) against isFilesystemRoot.
Source
Thrown at app-vite/lib/utils/remove-build-artifacts.js:72
projectDir,
allowOutsideProject
}) {
if (typeof targetDir !== 'string' || targetDir.trim() === '') {
throw new Error('Build output directory must be a non-empty path')
}
if (typeof projectDir !== 'string' || projectDir.trim() === '') {
throw new Error('Project directory must be a non-empty path')
}
const project = resolve(projectDir)
const effectiveProject = fse.realpathSync(project)
const home = fse.realpathSync(resolve(homedir()))
const target = resolve(projectDir, targetDir)
const effectiveTarget = getEffectivePath(target)
if (isFilesystemRoot(target) || isFilesystemRoot(effectiveTarget)) {
throw new Error('Refusing to remove a filesystem root as build output')
}
if (target === home || effectiveTarget === home) {
throw new Error(
'Refusing to remove the user home directory as build output'
)
}
if (target === project || effectiveTarget === effectiveProject) {
throw new Error('Refusing to remove the project root as build output')
}
if (
allowOutsideProject !== true &&
isContainedPath(effectiveProject, effectiveTarget) === false
) {
throw new Error(
'Build output directory must remain inside the project. Set build.allowOutsideProjectDistDir to true to explicitly allow an external directory.'View on GitHub (pinned to 4841521b5f)
Solutions
- Set distDir to a real subdirectory like 'dist' or 'build/output'
- Check for symlinks in the configured path ('ls -l') and repoint them away from the root
- Never interpolate unvalidated env vars directly into distDir; default to 'dist' when empty
Example fix
// before distDir: process.env.DIST_DIR || '/' // after distDir: process.env.DIST_DIR || 'dist'
Defensive patterns
Strategy: validation
Validate before calling
const path = require('node:path')
const { parse } = require('node:path')
function isFsRoot(p) {
const parsed = parse(path.resolve(p))
return parsed.root === path.resolve(p) && (parsed.dir === parsed.root)
}
const target = path.resolve(projectDir, distDir)
if (isFsRoot(target)) throw new Error('dist dir resolves to filesystem root') Try / catch
try {
await removeBuildArtifacts(opts)
} catch (err) {
if (err.message === 'Refusing to remove a filesystem root as build output') {
// fix distDir config; never bypass this guard
} else throw err
} Prevention
- Never set distDir to '/', a drive root, or raw unvalidated env vars
- Default to a relative 'dist' directory
- Check symlinks ('readlink -f') when distDir is an absolute path
- Treat this error as a config bug, not something to catch and continue
When it happens
Trigger: Configuring the build output directory as '/' (or 'C:/' etc.), or as a path that resolves via symlinks to a filesystem root — e.g. distDir pointing at a symlink named /dist that actually targets /.
Common situations: Setting distDir: '/' by mistake in quasar.config.js; a symlink farm or Docker volume mount mapping the dist dir to the container root; reading an empty environment variable that collapses the path to root after resolve.
Related errors
- Refusing to remove the user home directory as build output
- Refusing to remove the project root as build output
- Could not resolve an existing ancestor for "${target}"
- Build output directory must remain inside the project. Set b
- Could not generate ${assetRelativePath}.
AI-assisted analysis of quasarframework/quasar@4841521b5f (2026-08-30).
Data as JSON: /api/errors/03844005c88aafae.
Report an issue: GitHub.