{"record":{"id":"d752ce98804a054a","repo":"denoland/deno","slug":"declaration-file-is-not-under-the-current-direc","errorCode":null,"errorMessage":"Declaration file {} is not under the current directory","messagePattern":"Declaration file (.+?) is not under the current directory","errorType":"validation","errorClass":"anyhow::Error","httpStatus":null,"severity":"error","filePath":"cli/tools/transpile.rs","lineNumber":363,"sourceCode":"  tsc_file_name: &str,\n  output_dir: Option<&str>,\n  output_base_dir: Option<&Path>,\n  cwd: &Path,\n) -> Result<PathBuf, AnyError> {\n  // TSC emits file names like \"file:///path/to/file.d.ts\"\n  let path = if let Ok(specifier) = ModuleSpecifier::parse(tsc_file_name) {\n    deno_path_util::url_to_file_path(&specifier).with_context(|| {\n      format!(\"Cannot convert specifier to path: {tsc_file_name}\")\n    })?\n  } else {\n    PathBuf::from(tsc_file_name)\n  };\n\n  if let Some(outdir) = output_dir {\n    // --outdir: preserve relative directory structure\n    let outdir = cwd.join(outdir);\n    let relative = path.strip_prefix(cwd).map_err(|_| {\n      anyhow::anyhow!(\n        \"Declaration file {} is not under the current directory\",\n        path.display()\n      )\n    })?;\n    Ok(outdir.join(relative))\n  } else if let Some(base_dir) = output_base_dir {\n    // -o: place .d.ts next to the output file\n    let file_name = path\n      .file_name()\n      .ok_or_else(|| anyhow::anyhow!(\"Invalid declaration file path\"))?;\n    Ok(base_dir.join(file_name))\n  } else {\n    // No output specified: place next to source file\n    Ok(path)\n  }\n}\n\n/// SWC's code generator always writes a single space after a block","sourceCodeStart":345,"sourceCodeEnd":381,"githubUrl":"https://github.com/denoland/deno/blob/9ad36f7a2cce60488e6ec52283efb32efddaf93a/cli/tools/transpile.rs#L345-L381","documentation":"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.","triggerScenarios":"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.","commonSituations":"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.","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."],"exampleFix":"# before — input outside cwd + --outdir\n$ cd packages/app && deno transpile --declaration --outdir dist ../shared/lib.ts\nerror: Declaration file /repo/packages/shared/lib.d.ts is not under the current directory\n\n# after — run from the common root, or target a single output\n$ deno transpile --declaration --outdir dist packages/shared/lib.ts   # from repo root\n$ deno transpile --declaration --output dist/lib.js ../shared/lib.ts   # single-file mode","handlingStrategy":"validation","validationCode":"# Ensure all transpile inputs are under the current directory before using --outdir\nfor f in src/**/*.ts; do\n  case \"$(realpath \"$f\")\" in\n    \"$(pwd)\"/*) ;;\n    *) echo \"outside cwd: $f — use --output instead\"; exit 1;;\n  esac\ndone\ndeno transpile --declaration --outdir dist src/**/*.ts","typeGuard":null,"tryCatchPattern":null,"preventionTips":["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."],"tags":["transpile","outdir","declaration","path"],"backgroundTag":"path-outside-working-directory","analyzedSha":"9ad36f7a2cce60488e6ec52283efb32efddaf93a","analyzedAt":"2026-08-20T13:07:44.778Z","contentChangedAt":"2026-08-20T13:07:44.778Z","schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}