denoland/deno · error · AnyError

Could not determine directory of

Error message

Could not determine directory of '{}'

What it means

`deno link` computes the directory containing deno.json via Path::parent(). In Rust that returns None only for paths with no parent — a filesystem root such as `/` or `C:\`, or an empty path. In practice this fires only when the config path resolves to the volume root, which almost always indicates a misdirected or accidental config location rather than a normal project layout.

Solutions

  1. Move the project (and its deno.json) into a real subdirectory and re-run from there
  2. Fix or unset config-path overrides that point at the volume root
  3. In containers, set WORKDIR to a subdirectory such as /app instead of /

Example fix

# before (Dockerfile)
WORKDIR /
deno link ../shared

# after
WORKDIR /app
deno link ../shared
Defensive patterns

Strategy: validation

Validate before calling

const configDir = configPath.replace(/\/[^\/]*$/, '');
if (configDir === '' || configDir === '/') {
  throw new Error('deno.json lives at the filesystem root; move the project into a subdirectory');
}

Prevention

When it happens

Trigger: deno.json resolved to the filesystem root — e.g. running in `/` with a deno.json created there, or an explicit config path pointing at `/deno.json` — so deno_config.path.parent() is None at cli/tools/pm/mod.rs:1473.

Common situations: Containers whose WORKDIR is /; configs mistakenly initialized at the root; absolute config-path overrides pointing at the volume root; essentially never in normal nested projects.

Related errors


AI-assisted analysis of denoland/deno@9ad36f7a2c (2026-08-20). Data as JSON: /api/errors/9a147b64ed8c2429. Report an issue: GitHub.

Appendix: source

Thrown at cli/tools/pm/mod.rs:1473

      ConfigKind::DenoJson,
      url_to_file_path(&deno_json.specifier)?,
    )?,
    None => bail!("No deno.json found; there are no linked packages to unlink"),
  };
  Ok((cli_factory, deno_config))
}

pub async fn link(
  flags: Arc<Flags>,
  link_flags: LinkFlags,
) -> Result<(), AnyError> {
  let (cli_factory, mut deno_config) = load_deno_config_for_link(&flags, true)?;
  let cwd = cli_factory.cli_options()?.initial_cwd().to_path_buf();
  let config_dir = deno_config
    .path
    .parent()
    .ok_or_else(|| {
      deno_core::anyhow::anyhow!(
        "Could not determine directory of '{}'",
        deno_config.path.display()
      )
    })?
    .to_path_buf();

  // Validate every path and compute the relative form we'll store.
  let mut resolved = Vec::with_capacity(link_flags.paths.len());
  for raw_path in &link_flags.paths {
    let abs = resolve_link_path(&cwd, raw_path);
    if !abs.exists() {
      bail!("Cannot link '{}': directory does not exist", raw_path);
    }
    if !abs.is_dir() {
      bail!("Cannot link '{}': not a directory", raw_path);
    }
    let has_config =
      abs.join("deno.json").exists() || abs.join("deno.jsonc").exists();

View on GitHub (pinned to 9ad36f7a2c)