denoland/deno · critical
expected file "{file}" to exist
Error message
expected file "{file}" to exist What it means
Deno's CLI build script zstd-compresses checked-in JS sources (cli/tsc/99_main_compiler.js, 97_ts_host.js, 98_lsp.js, 00_typescript.js, and the tsc/dts .d.ts set) for release builds. compress_source (cli/build.rs:219-249) canonicalizes each listed path and panics 'expected file ... to exist' when canonicalize fails, i.e. the file is registered for compression but missing from the checkout. Compression only runs when !cfg!(debug_assertions) (build.rs:190), so debug builds pass while release builds and cargo publish verification fail.
Source
Thrown at cli/build.rs:223
let relative_str = relative.to_string_lossy().replace('\\', "/");
generated.push_str(&format!(
" maybe_compressed_static_asset!(\"{}\", false),\n",
relative_str
));
}
generated.push_str(" ]\n");
generated.push_str(" };\n");
generated.push_str("}\n");
std::fs::write(out_dir.join("node_types.rs"), generated).unwrap();
}
fn compress_source(out_dir: &Path, file: &str) {
#[allow(clippy::disallowed_methods, reason = "build code")]
let path = Path::new(file)
.canonicalize()
.unwrap_or_else(|_| panic!("expected file \"{file}\" to exist"));
let contents = std::fs::read(&path).unwrap();
println!("cargo:rerun-if-changed={}", path.display());
let compressed = zstd::bulk::compress(&contents, 19).unwrap();
let mut out = out_dir.join(file.trim_start_matches("../"));
let mut ext = out
.extension()
.map(|s| s.to_string_lossy())
.unwrap_or_default()
.into_owned();
ext.push_str(".zstd");
out.set_extension(ext);
std::fs::create_dir_all(out.parent().unwrap()).unwrap();
let mut file = std::fs::OpenOptions::new()
.create(true)
.truncate(true)
.write(true)View on GitHub (pinned to 9ad36f7a2c)
Solutions
- Restore the exact path from the panic text: git status --short cli/tsc, then git checkout -- cli/tsc (or rerun the step that generates the tsc bundle).
- Clear the build-script output cache so the file list is recomputed: cargo clean -p deno or remove target/**/build/deno-*/.
- Verify the file exists (ls cli/tsc/<file>) before rebuilding; if it is genuinely untracked, regenerate or re-checkout rather than touching build.rs.
Example fix
# before cargo build --release # panic: expected file "../tsc/00_typescript.js" to exist # after git checkout -- cli/tsc cargo build --release
Defensive patterns
Strategy: validation
Validate before calling
# preflight before a release build
for f in cli/tsc/00_typescript.js cli/tsc/97_ts_host.js \
cli/tsc/98_lsp.js cli/tsc/99_main_compiler.js; do
test -f "$f" || { echo "missing $f — run: git checkout -- cli/tsc"; exit 1; }
done
compgen -G 'cli/tsc/dts/*.d.ts' > /dev/null || { echo 'missing dts files'; exit 1; } Prevention
- Verify cli/tsc assets exist before release builds — the panic only fires without debug assertions
- After branch switches that change the .d.ts set, cargo clean -p deno to refresh the build-script manifest
- Avoid clones that skip or shallow-filter cli/tsc; do not gitignore generated tsc bundles
When it happens
Trigger: cargo build --release or cargo publish with one of cli/tsc/*.js or a tsc/dts/*.d.ts absent; partial or shallow clones; stale OUT_DIR file lists after files were added/renamed; a file removed by tooling or a bad .gitignore rule.
Common situations: Fresh machines where the generated/checked-out tsc assets are incomplete; branch switches that change the .d.ts set while the build cache keeps an old manifest; case-insensitive filesystems mis-checking-out differing capitalizations.
Related errors
- cli/laufey_sums.lock has no pinned laufey version — populate
- cli/laufey_sums.lock pins Laufey v{pinned} but this build ex
- checked-in AppImage runtime stub {} does not match the SHA-2
- {ENABLE_ENV} must be unset or set to 1
- startup ordering is only supported by the release profile
AI-assisted analysis of denoland/deno@9ad36f7a2c (2026-08-20).
Data as JSON: /api/errors/48b4aa37daf78a0f.
Report an issue: GitHub.