{"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":"exception","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/89f33cbef296a2b287f323d42de54c871fa69c77/cli/tools/transpile.rs#L345-L381","documentation":"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.","triggerScenarios":"`deno transpile --declaration --outdir dist ../other/mod.ts` — a source file living outside the current working directory while --outdir is set.","commonSituations":"Running the command from a subdirectory while inputs live in a sibling tree; build scripts invoked with paths from a different root.","solutions":["Run deno from a common ancestor of all inputs (e.g. the repo root) so every source is under cwd","Use --output for a single outside file — it accepts any path","Drop --outdir so declarations land next to their sources regardless of cwd"],"exampleFix":"# before (cwd = packages/one)\ndeno transpile --declaration --outdir dist ../two/mod.ts\n# after (cwd = packages)\ndeno transpile --declaration --outdir one/dist one/mod.ts two/mod.ts","handlingStrategy":"validation","validationCode":"# bash: verify every input is under cwd before using --outdir\nfor f in \"$@\"; do\n  case \"$(realpath \"$f\")\" in\n    \"$(pwd)\"/*) ;;\n    *) echo \"input outside cwd: $f — run from a common ancestor or use --output\" >&2; exit 1;;\n  esac\ndone\ndeno transpile --declaration --outdir dist \"$@\"","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Invoke deno from the repo root (or a common ancestor of all inputs) when using --outdir","Use --output for one-off files outside the working tree","Encourage CI to pin a fixed working directory per step"],"tags":["cli","transpile","declarations","paths","outdir"],"backgroundTag":null,"analyzedSha":"89f33cbef296a2b287f323d42de54c871fa69c77","analyzedAt":"2026-08-16T07:54:21.310Z","schemaVersion":2},"datasetVersion":"2026-08-16T08:17:34.114Z"}