quasarframework/quasar · error · Error

Build output directory must be a non-empty path

Error message

Build output directory must be a non-empty path

What it means

getBuildArtifactsCleanTarget validates the options for the build-artifact removal step before touching the filesystem. It throws 'Build output directory must be a non-empty path' when targetDir is not a non-empty (after trim) string, because deleting an empty/invalid target would be ambiguous and dangerous.

Source

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

function getEffectivePath(target) {
  const existingAncestor = getExistingAncestor(target)
  const realAncestor = fse.realpathSync(existingAncestor)

  return resolve(realAncestor, relative(existingAncestor, target))
}

function isFilesystemRoot(target) {
  return target === parse(target).root
}

export function getBuildArtifactsCleanTarget({
  targetDir,
  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(

View on GitHub (pinned to 4841521b5f)

Solutions

  1. Set a valid distDir/build output directory in quasar.config.js (e.g. distDir: 'dist')
  2. Check that the code populating targetDir actually resolves the value (log it before the call)
  3. Ensure the option key name matches the API (targetDir) and is a string, not a path object

Example fix

// before
await removeBuildArtifacts({ targetDir: undefined, projectDir: process.cwd() })
// after
await removeBuildArtifacts({ targetDir: 'dist', projectDir: process.cwd() })
Defensive patterns

Strategy: validation

Validate before calling

function assertNonEmptyString(v, name) {
  if (typeof v !== 'string' || v.trim() === '') throw new TypeError(`${name} must be a non-empty string`)
}
assertNonEmptyString(opts.targetDir, 'targetDir')

Type guard

function isNonEmptyString(v) {
  return typeof v === 'string' && v.trim() !== ''
}
// usage: if (isNonEmptyString(opts.targetDir)) { ... }

Try / catch

try {
  await removeBuildArtifacts(opts)
} catch (err) {
  if (err.message === 'Build output directory must be a non-empty path') {
    // default to 'dist' or surface a config error
  } else throw err
}

Prevention

When it happens

Trigger: Passing targetDir as undefined, null, a non-string, '' or whitespace-only to the clean-artifacts API — typically when build.buildDir/distDir is missing from the resolved config or an option was misread.

Common situations: A quasar.config.js with no distDir and a plugin reading it as undefined; programmatic use of the cleaner with a hand-built options object omitting targetDir; config parsing returning empty strings for empty config values.

Related errors


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