{"record":{"id":"65d19d00846e02c7","repo":"denoland/deno","slug":"path-not-found-not-dir","errorCode":null,"errorMessage":"path not found (not dir): {}","messagePattern":"path not found \\(not dir\\): (.+?)","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"cli/rt/file_system.rs","lineNumber":1295,"sourceCode":"          let dest = symlink.resolve_dest_from_root(&self.root_path);\n          let (resolved_path, entry) =\n            self.find_entry_inner(&dest, seen, case_sensitivity)?;\n          final_path = resolved_path; // overwrite with the new resolved path\n          match entry {\n            VfsEntryRef::Dir(dir) => {\n              final_path.push(component);\n              dir\n            }\n            _ => {\n              return Err(std::io::Error::new(\n                std::io::ErrorKind::NotFound,\n                format!(\"path not found (symlink not dir): {}\", path.display()),\n              ));\n            }\n          }\n        }\n        _ => {\n          return Err(std::io::Error::new(\n            std::io::ErrorKind::NotFound,\n            format!(\"path not found (not dir): {}\", path.display()),\n          ));\n        }\n      };\n      let component = component.to_string_lossy();\n      current_entry = current_dir\n        .entries\n        .get_by_name(&component, case_sensitivity)\n        .ok_or_else(|| {\n          std::io::Error::new(\n            std::io::ErrorKind::NotFound,\n            format!(\"path not found (entry missing): {}\", path.display()),\n          )\n        })?\n        .as_ref();\n    }\n","sourceCodeStart":1277,"sourceCodeEnd":1313,"githubUrl":"https://github.com/denoland/deno/blob/9ad36f7a2cce60488e6ec52283efb32efddaf93a/cli/rt/file_system.rs#L1277-L1313","documentation":"Thrown while resolving a path inside the embedded virtual filesystem (VFS) of a compiled Deno binary. `find_entry_no_follow` walks the path component by component; when an intermediate component resolves to a VFS entry that is neither a directory nor a followable symlink (i.e. a regular file), traversal cannot descend into it and the lookup fails with `io::ErrorKind::NotFound`. The `{}` placeholder is the full requested path.","triggerScenarios":"Any file-system API call against the embedded VFS where a non-final path component names a file, e.g. `Deno.readTextFile(\"./mod.ts/helper\")` in a `deno compile` binary, or code that concatenates a filename with an extra `/segment`. It fires during component descent, before the final name is even looked up.","commonSituations":"Typos appending a suffix after a filename (\"./data.bin\" + \"/part\"); path templates where a file sits where the code expects a directory; assets restructured after the code was written but before the binary was rebuilt.","solutions":["Check the printed path and remove the segment that follows the file component — the file named in the middle of the path is being treated as a directory.","Probe the path with `Deno.stat` at startup and log the offending component before the failing call.","If the layout is intentional, restructure the assets so containers are directories, then recompile with `deno compile`."],"exampleFix":"// before\nconst cfg = await Deno.readTextFile(\"./assets/data.json/part\"); // data.json is a file\n\n// after\nconst cfg = await Deno.readTextFile(\"./assets/data.json\");","handlingStrategy":"validation","validationCode":"// probe the parent chain before first use (compiled binaries)\nasync function assertTraversable(path: string) {\n  const parts = path.split(/[\\\\/]/).filter(Boolean);\n  let cur = \".\";\n  for (const p of parts.slice(0, -1)) {\n    cur += \"/\" + p;\n    const st = await Deno.stat(cur); // throws NotFound if missing\n    if (!st.isDirectory) throw new Error(`not a directory: ${cur}`);\n  }\n}","typeGuard":"function isDirectory(st: Deno.FileInfo | null): st is Deno.FileInfo {\n  return st !== null && st.isDirectory;\n}","tryCatchPattern":"try {\n  const data = await Deno.readFile(p);\n} catch (err) {\n  if (err instanceof Deno.errors.NotFound) {\n    // inspect err.message: \"(not dir)\" = mid-path file, \"(entry missing)\" = absent leaf\n  } else throw err;\n}","preventionTips":["Build paths from typed segments, never string concatenation of file paths and suffixes","Smoke-test compiled binaries against the real asset tree in CI","Validate asset layouts with a startup probe before the hot code path"],"tags":["vfs","path-resolution","standalone-binary","deno-compile","file-not-found"],"backgroundTag":"path-component-not-a-directory","analyzedSha":"9ad36f7a2cce60488e6ec52283efb32efddaf93a","analyzedAt":"2026-08-20T13:07:44.778Z","schemaVersion":2},"datasetVersion":"2026-08-31T09:17:48.483Z"}