denoland/deno · error · anyhow::Error
Invalid declaration file path
Error message
Invalid declaration file path
What it means
When placing a declaration next to a `--output` file, the code needs the declaration path's final component via `path.file_name()`; for degenerate paths (a filesystem root, or a path ending in `..`) it returns None and this guard fires. It is a defensive check against malformed tsc-reported output paths.
Source
Thrown at cli/tools/transpile.rs:373
} else {
PathBuf::from(tsc_file_name)
};
if let Some(outdir) = output_dir {
// --outdir: preserve relative directory structure
let outdir = cwd.join(outdir);
let relative = path.strip_prefix(cwd).map_err(|_| {
anyhow::anyhow!(
"Declaration file {} is not under the current directory",
path.display()
)
})?;
Ok(outdir.join(relative))
} else if let Some(base_dir) = output_base_dir {
// -o: place .d.ts next to the output file
let file_name = path
.file_name()
.ok_or_else(|| anyhow::anyhow!("Invalid declaration file path"))?;
Ok(base_dir.join(file_name))
} else {
// No output specified: place next to source file
Ok(path)
}
}
/// SWC's code generator always writes a single space after a block
/// comment's closing `*/`, regardless of whether the original source had a
/// newline. For multi-line block comments (typically JSDoc) this collapses
/// the comment onto the same line as the following statement. This function
/// walks the emitted source and replaces that single space with a newline
/// (plus the comment's own leading indentation) when the preceding block
/// comment spans multiple lines.
fn restore_block_comment_newlines(input: &str) -> String {
let bytes = input.as_bytes();
let n = bytes.len();
let mut out: Vec<u8> = Vec::with_capacity(n);View on GitHub (pinned to 89f33cbef2)
Solutions
- Re-run without -o (default placement next to sources) to see whether the malformed path reproduces
- If it reproduces, capture the command, inputs, and printed path and report an issue to the deno repository
Defensive patterns
Strategy: fallback
Try / catch
# shell: retry without -o placement if the defensive guard trips if ! deno transpile mod.ts --declaration -o out/mod.js 2>err.log; then grep -q "Invalid declaration file path" err.log && deno transpile mod.ts --declaration # default placement next to source fi
Prevention
- Prefer default (next-to-source) declaration placement; use -o only when the path is known sane
- Keep toolchain versions pinned so tsc output paths stay predictable
- Report reproductions upstream — this guard indicates abnormal compiler output
When it happens
Trigger: A declaration file name reported by the native compiler that has no final component while using -o. Practically unreachable through normal CLI use.
Common situations: Not user-triggered in practice; would indicate corrupt/abnormal tsc output or a path-manipulation bug in deno itself.
Related errors
- Declaration file {} is not under the current directory
- Cannot use --declaration without --output or --outdir. Decla
- Invalid file path: {}
- Cannot generate declarations for files with different compil
- Input file {} is not under the current directory. Use --outp
AI-assisted analysis of denoland/deno@89f33cbef2 (2026-08-16).
Data as JSON: /api/errors/06eef6ac8201183e.
Report an issue: GitHub.