denoland/deno · error

Cannot build a .msi from an empty app directory

Error message

Cannot build a .msi from an empty app directory

What it means

The MSI builder walks the staged app directory and collects every file into install components; an MSI with zero files is meaningless, so the build bails when the walk produced nothing. It means the directory the bundler was pointed at is empty — usually the preceding compile/bundle step failed to place output, or the path is wrong.

Source

Thrown at cli/tools/desktop.rs:4746

    let long = rel
      .file_name()
      .map(|s| s.to_string_lossy().into_owned())
      .unwrap_or_else(|| key.clone());
    short_counter += 1;
    files.push(MsiFile {
      key,
      component,
      file_name: format!(
        "{}|{}",
        msi_short_name(short_counter, &long, false),
        long
      ),
      size: *size,
      abs_path: app_dir.join(rel),
    });
  }
  if files.is_empty() {
    bail!("Cannot build a .msi from an empty app directory");
  }

  // Locate the laufey launcher in the install root so we can author a Start Menu
  // shortcut to it (otherwise the installed app is not discoverable — there is no
  // icon anywhere, only files under Program Files). The launcher is the backend
  // binary renamed to `<app>.exe`; it auto-loads the co-located `<app>.dll`
  // runtime, so the shortcut targets it directly with no arguments.
  let launcher_exe = format!("{app_name}.exe").to_ascii_lowercase();
  let shortcut_target = rel_files
    .iter()
    .zip(files.iter())
    .find(|((rel, _), _)| {
      rel.parent() == Some(Path::new(""))
        && rel
          .file_name()
          .and_then(|n| n.to_str())
          .is_some_and(|n| n.to_ascii_lowercase() == launcher_exe)
    })

View on GitHub (pinned to f7822238ca)

Solutions

  1. Verify the app directory actually contains your compiled output (list its files) before the MSI step.
  2. Re-run the preceding build/compile step and confirm it succeeded before packaging.
  3. Check the --output / staging path configuration for typos or wrong job-workspace paths in CI.
Defensive patterns

Strategy: validation

Validate before calling

# Fail the pipeline before the MSI step if the staged app dir is empty
[ -n "$(find "$APP_DIR" -type f -print -quit)" ] || {
  echo "app dir '$APP_DIR' is empty — compile step produced nothing"; exit 1;
}

Prevention

When it happens

Trigger: `deno desktop` packaging a .msi where the app directory contains no files: an earlier build stage failed silently, the output/staging path is misconfigured, or a cleanup step emptied it between stages.

Common situations: CI pipelines where the compile step and packaging step are separate jobs and artifacts didn't transfer; wrong --output path pointing at a freshly-created empty dir.

Related errors


AI-assisted analysis of denoland/deno@f7822238ca (2026-08-20). Data as JSON: /api/errors/513c518ce3bb07f6. Report an issue: GitHub.