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 `--outdir`, each emitted .d.ts destination is computed as outdir + path-relative-to-cwd via `strip_prefix(cwd)`. If a declaration's source path is not under the current directory, the strip fails and this error names the offending path.

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 block

View on GitHub (pinned to 89f33cbef2)

Solutions

  1. Run deno from a common ancestor of all inputs (e.g. the repo root) so every source is under cwd
  2. Use --output for a single outside file — it accepts any path
  3. Drop --outdir so declarations land next to their sources regardless of cwd

Example fix

# before (cwd = packages/one)
deno transpile --declaration --outdir dist ../two/mod.ts
# after (cwd = packages)
deno transpile --declaration --outdir one/dist one/mod.ts two/mod.ts
Defensive patterns

Strategy: validation

Validate before calling

# bash: verify every input is under cwd before using --outdir
for f in "$@"; do
  case "$(realpath "$f")" in
    "$(pwd)"/*) ;;
    *) echo "input outside cwd: $f — run from a common ancestor or use --output" >&2; exit 1;;
  esac
done
deno transpile --declaration --outdir dist "$@"

Prevention

When it happens

Trigger: `deno transpile --declaration --outdir dist ../other/mod.ts` — a source file living outside the current working directory while --outdir is set.

Common situations: Running the command from a subdirectory while inputs live in a sibling tree; build scripts invoked with paths from a different root.

Related errors


AI-assisted analysis of denoland/deno@89f33cbef2 (2026-08-16). Data as JSON: /api/errors/d752ce98804a054a. Report an issue: GitHub.