quasarframework/quasar · error · Error

Build output directory must remain inside the project. Set b

Error message

Build output directory must remain inside the project. Set build.allowOutsideProjectDistDir to true to explicitly allow an external directory.

What it means

By default the build-artifact cleaner only deletes directories contained within the project. When the resolved build output directory (after symlink resolution) lies outside the effective project directory and allowOutsideProject is not exactly true, this error is thrown so an external directory is never deleted implicitly.

Source

Thrown at app-vite/lib/utils/remove-build-artifacts.js:89

  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.'
    )
  }

  return { target, effectiveTarget }
}

export function removeBuildArtifacts(options) {
  const { target, effectiveTarget } = getBuildArtifactsCleanTarget(options)

  if (fse.pathExistsSync(target) === false) return

  const symlinkTarget =
    target !== effectiveTarget ? ` (resolves to: ${effectiveTarget})` : ''

  log(`Removing build artifacts: ${target}${symlinkTarget}`)

  if (fse.lstatSync(target).isSymbolicLink()) {

View on GitHub (pinned to 4841521b5f)

Solutions

  1. Add build: { allowOutsideProjectDistDir: true } to quasar.config.js if the external directory is intentional
  2. Prefer moving the output inside the project (distDir: 'dist') and copy/symlink it in your deploy step
  3. Ensure the flag is the boolean true, not the string 'true' or 1

Example fix

// before
build: { distDir: '../www/app' }
// after
build: { distDir: '../www/app', allowOutsideProjectDistDir: true }
Defensive patterns

Strategy: validation

Validate before calling

const path = require('node:path')
const fs = require('node:fs')
const project = fs.realpathSync(path.resolve(projectDir))
const target = fs.realpathSync(path.resolve(projectDir, distDir))
const inside = target === project || target.startsWith(project + path.sep)
if (!inside && allowOutsideProjectDistDir !== true) {
  throw new Error('dist dir is outside the project; set build.allowOutsideProjectDistDir: true')
}

Try / catch

try {
  await removeBuildArtifacts(opts)
} catch (err) {
  if (err.message.includes('must remain inside the project')) {
    // either move dist inside the project or opt in explicitly
  } else throw err
}

Prevention

When it happens

Trigger: distDir configured as an absolute path outside the project (e.g. ../shared-dist or /var/www/app) while the quasar.config.js build option build.allowOutsideProjectDistDir is absent or not strictly true.

Common situations: Deploy setups pointing dist at a sibling webroot; monorepo outputs shared across packages; forgetting the exact boolean true (a truthy string 'true' is not accepted).

Related errors


AI-assisted analysis of quasarframework/quasar@4841521b5f (2026-08-30). Data as JSON: /api/errors/b9ffef9588b63416. Report an issue: GitHub.