denoland/deno · error · anyhow::Error
Declaration file is not under the current directory
Error message
Declaration file {} is not under the current directory What it means
With `deno transpile --declaration --outdir <dir>`, emitted .d.ts files mirror the source tree: resolve_dts_output_path strips the current directory from each declaration path (transpile.rs:359-368). tsc reports specifiers as normalized file:// URLs, so `../` inputs collapse outside cwd and absolute inputs into other trees fail strip_prefix — Deno then cannot compute the relative layout and errors.
Solutions
- Run from a common ancestor (e.g. the repo root) so every input lies under the current directory.
- Use single-file output instead: `deno transpile --declaration --output dist/lib.js <input>` — -o places the .d.ts next to the output file without needing a relative tree.
- Copy or symlink the external sources under cwd for the duration of the build.
Example fix
# before — input outside cwd + --outdir $ cd packages/app && deno transpile --declaration --outdir dist ../shared/lib.ts error: Declaration file /repo/packages/shared/lib.d.ts is not under the current directory # after — run from the common root, or target a single output $ deno transpile --declaration --outdir dist packages/shared/lib.ts # from repo root $ deno transpile --declaration --output dist/lib.js ../shared/lib.ts # single-file mode
Defensive patterns
Strategy: validation
Validate before calling
# Ensure all transpile inputs are under the current directory before using --outdir
for f in src/**/*.ts; do
case "$(realpath "$f")" in
"$(pwd)"/*) ;;
*) echo "outside cwd: $f — use --output instead"; exit 1;;
esac
done
deno transpile --declaration --outdir dist src/**/*.ts Prevention
- Invoke deno transpile --outdir from a common ancestor of all inputs (repo root).
- Prefer --output for single-file or out-of-tree inputs; --outdir only works with a relative tree.
- Avoid ../ inputs with --outdir — file:// URL normalization resolves them outside cwd.
When it happens
Trigger: deno transpile --declaration --outdir dist ../shared/lib.ts from a subpackage (URL normalization resolves it outside cwd), or an absolute input like /opt/other/a.ts; also when cwd was changed with -C but inputs are given relative to another directory.
Common situations: Transpiling a sibling package's sources from an app folder; CI invoking deno from a different working directory than the sources; build scripts mixing absolute and relative inputs.
Related errors
- Input file is not under the current directory. Use --output…
- Invalid declaration file path
- Invalid file path
- app bundle has no name
- Could not get parent of
AI-assisted analysis of denoland/deno@9ad36f7a2c (2026-08-20).
Data as JSON: /api/errors/d752ce98804a054a.
Report an issue: GitHub.
Appendix: source
Thrown at cli/tools/transpile.rs:363
tsc_file_name: &str,
output_dir: Option<&str>,
output_base_dir: Option<&Path>,
cwd: &Path,
) -> Result<PathBuf, AnyError> {
// TSC emits file names like "file:///path/to/file.d.ts"
let path = if let Ok(specifier) = ModuleSpecifier::parse(tsc_file_name) {
deno_path_util::url_to_file_path(&specifier).with_context(|| {
format!("Cannot convert specifier to path: {tsc_file_name}")
})?
} 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 blockView on GitHub (pinned to 9ad36f7a2c)