{"record":{"id":"9a147b64ed8c2429","repo":"denoland/deno","slug":"could-not-determine-directory-of","errorCode":null,"errorMessage":"Could not determine directory of '{}'","messagePattern":"Could not determine directory of '(.+?)'","errorType":"exception","errorClass":"AnyError","httpStatus":null,"severity":"error","filePath":"cli/tools/pm/mod.rs","lineNumber":1473,"sourceCode":"      ConfigKind::DenoJson,\n      url_to_file_path(&deno_json.specifier)?,\n    )?,\n    None => bail!(\"No deno.json found; there are no linked packages to unlink\"),\n  };\n  Ok((cli_factory, deno_config))\n}\n\npub async fn link(\n  flags: Arc<Flags>,\n  link_flags: LinkFlags,\n) -> Result<(), AnyError> {\n  let (cli_factory, mut deno_config) = load_deno_config_for_link(&flags, true)?;\n  let cwd = cli_factory.cli_options()?.initial_cwd().to_path_buf();\n  let config_dir = deno_config\n    .path\n    .parent()\n    .ok_or_else(|| {\n      deno_core::anyhow::anyhow!(\n        \"Could not determine directory of '{}'\",\n        deno_config.path.display()\n      )\n    })?\n    .to_path_buf();\n\n  // Validate every path and compute the relative form we'll store.\n  let mut resolved = Vec::with_capacity(link_flags.paths.len());\n  for raw_path in &link_flags.paths {\n    let abs = resolve_link_path(&cwd, raw_path);\n    if !abs.exists() {\n      bail!(\"Cannot link '{}': directory does not exist\", raw_path);\n    }\n    if !abs.is_dir() {\n      bail!(\"Cannot link '{}': not a directory\", raw_path);\n    }\n    let has_config =\n      abs.join(\"deno.json\").exists() || abs.join(\"deno.jsonc\").exists();","sourceCodeStart":1455,"sourceCodeEnd":1491,"githubUrl":"https://github.com/denoland/deno/blob/9ad36f7a2cce60488e6ec52283efb32efddaf93a/cli/tools/pm/mod.rs#L1455-L1491","documentation":"`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.","triggerScenarios":"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.","commonSituations":"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.","solutions":["Move the project (and its deno.json) into a real subdirectory and re-run from there","Fix or unset config-path overrides that point at the volume root","In containers, set WORKDIR to a subdirectory such as /app instead of /"],"exampleFix":"# before (Dockerfile)\nWORKDIR /\ndeno link ../shared\n\n# after\nWORKDIR /app\ndeno link ../shared","handlingStrategy":"validation","validationCode":"const configDir = configPath.replace(/\\/[^\\/]*$/, '');\nif (configDir === '' || configDir === '/') {\n  throw new Error('deno.json lives at the filesystem root; move the project into a subdirectory');\n}","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Never place deno.json at a filesystem root","Prefer subdirectory workdirs in containers and CI","Validate generated config locations"],"tags":["pm","link","filesystem","config-path"],"backgroundTag":"invalid-config-path","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"}