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
- Verify the app directory actually contains your compiled output (list its files) before the MSI step.
- Re-run the preceding build/compile step and confirm it succeeded before packaging.
- 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
- Chain compile and packaging steps in one job, or verify artifacts transferred between CI jobs.
- Assert non-empty output dirs after every build stage, not just before MSI.
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
- No MSI architecture mapping for arch '{other}'; supported: x
- deno.json `version` "{version}" cannot be used as an MSI Pro
- refusing zip entry with unsafe path: {}
- hdiutil failed to create DMG at {}
- No bundled AppImage runtime for arch '{other}'; supported: x
AI-assisted analysis of denoland/deno@f7822238ca (2026-08-20).
Data as JSON: /api/errors/513c518ce3bb07f6.
Report an issue: GitHub.