{"record":{"id":"843c96b0e19364b6","repo":"affaan-m/ECC","slug":"nasiko-install-directory-has-no-resolvable-filesys","errorCode":null,"errorMessage":"Nasiko install directory has no resolvable filesystem ancestor.","messagePattern":"Nasiko install directory has no resolvable filesystem ancestor\\.","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"scripts/lib/nasiko-release.js","lineNumber":177,"sourceCode":"}\n\nfunction defaultInstallDirectory(normalized, environment = process.env, homeDirectory = os.homedir()) {\n  if (normalized.os === 'windows') {\n    if (!environment.LOCALAPPDATA) throw new Error('LOCALAPPDATA is required on Windows.');\n    return path.join(environment.LOCALAPPDATA, 'nasiko', 'bin');\n  }\n  return path.join(homeDirectory, '.local', 'bin');\n}\n\nfunction validateInstallDirectory(directory) {\n  if (typeof directory !== 'string' || directory.includes('\\0') || !path.isAbsolute(directory)) throw new Error('Nasiko install directory must be an absolute path.');\n  if (/^(?:\\\\\\\\|\\\\\\\\\\?\\\\|\\\\\\\\\\.\\\\)/.test(directory)) throw new Error('Nasiko install directory must be on a local filesystem.');\n  const resolved = path.resolve(directory);\n  if (resolved === path.parse(resolved).root) throw new Error('Nasiko cannot install directly into a filesystem root.');\n  let ancestor = resolved;\n  while (!fs.existsSync(ancestor)) {\n    const parent = path.dirname(ancestor);\n    if (parent === ancestor) throw new Error('Nasiko install directory has no resolvable filesystem ancestor.');\n    ancestor = parent;\n  }\n  const canonical = fs.realpathSync(ancestor);\n  return path.join(canonical, path.relative(ancestor, resolved));\n}\n\nfunction assertPrivateInstallDirectory(directory) {\n  const stats = fs.lstatSync(directory);\n  if (!stats.isDirectory() || stats.isSymbolicLink()) throw new Error('Nasiko install directory must be a real directory, not a symlink.');\n  if (process.platform !== 'win32') {\n    if (typeof process.getuid === 'function' && stats.uid !== process.getuid()) throw new Error('Nasiko install directory must be owned by the current user.');\n    if ((stats.mode & 0o022) !== 0) throw new Error('Nasiko install directory must not be group- or world-writable.');\n  }\n}\n\nfunction metadataPathFor(executable) { return path.join(path.dirname(executable), METADATA_FILENAME); }\n\nfunction readBoundedRegularFile(filePath, maximumBytes) {","sourceCodeStart":159,"sourceCodeEnd":195,"githubUrl":"https://github.com/affaan-m/ECC/blob/8321021c54d670126ce3b2969d5deb880b4b0c2a/scripts/lib/nasiko-release.js#L159-L195","documentation":"validateInstallDirectory walks up from the requested install path until it finds an existing ancestor so it can canonicalize the path via fs.realpathSync. If the walk reaches the filesystem root without ever finding an existing directory (every component is nonexistent, or the path cannot be resolved), it throws this error. It prevents installing into a path that has no real anchor on the filesystem.","triggerScenarios":"Calling installNasiko({installDir: ...}) or parseMutationArguments/parseStatusArguments with an absolute path where every ancestor component is missing, or a path whose only 'root' is not an existing mount (e.g. a drive letter or deeply nested path under a nonexistent volume).","commonSituations":"Typos in installDir config like '/nonexistent-vol/nasiko/bin' where even '/'-level mount detection fails; using a path on an unmounted drive or network share; CI containers where the HOME drive root is not resolvable; passing '/volumes/ghost/...' on macOS after an unmount.","solutions":["Check that some ancestor of the path actually exists: run `ls` (or `test -d`) on each parent component and create a real base directory first.","Mount or reconnect the drive/volume that the path lives on.","Use the default install directory (LOCALAPPDATA on Windows, ~/.local/bin elsewhere) by omitting installDir.","Fix typos in the configured path; verify it is absolute and not a UNC/network path."],"exampleFix":"// before\ninstallNasiko({ installDir: '/mnt/ghostdrive/nasiko/bin', yes: true })\n// after\nfs.mkdirSync('/mnt/real-drive/nasiko', { recursive: true })\ninstallNasiko({ installDir: '/mnt/real-drive/nasiko/bin', yes: true })","handlingStrategy":"validation","validationCode":"function installDirHasAncestor(dir) {\n  let cur = path.resolve(dir)\n  while (!fs.existsSync(cur)) {\n    const parent = path.dirname(cur)\n    if (parent === cur) return false\n    cur = parent\n  }\n  return true\n}\nif (!installDirHasAncestor('/mnt/ghost/nasiko/bin')) throw new Error('create a real base directory first')","typeGuard":"const isNonRootExistingAncestor = (dir) => {\n  let cur = path.resolve(dir)\n  while (!fs.existsSync(cur)) {\n    const p = path.dirname(cur)\n    if (p === cur) return false\n    cur = p\n  }\n  return cur !== path.parse(cur).root\n}","tryCatchPattern":"try {\n  await installNasiko({ installDir: dir, yes: true })\n} catch (e) {\n  if (e.message.includes('no resolvable filesystem ancestor')) {\n    fs.mkdirSync(dir, { recursive: true })\n    return installNasiko({ installDir: dir, yes: true })\n  }\n  throw e\n}","preventionTips":["Verify the target volume/drive is mounted before installing.","Pre-create the base directory with mkdir -p and point installDir inside it.","Default to the library's default install directory unless you have a specific need.","Lint CI configs for paths on ephemeral or unmounted volumes."],"tags":["filesystem","path-resolution","install-directory"],"backgroundTag":"directory-not-found","analyzedSha":"8321021c54d670126ce3b2969d5deb880b4b0c2a","analyzedAt":"2026-09-16T10:08:13.343Z","contentChangedAt":"2026-09-16T10:08:13.343Z","schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}