affaan-m/ECC · error

Nasiko install directory has no resolvable filesystem…

Error message

Nasiko install directory has no resolvable filesystem ancestor.

What it means

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.

Solutions

  1. 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.
  2. Mount or reconnect the drive/volume that the path lives on.
  3. Use the default install directory (LOCALAPPDATA on Windows, ~/.local/bin elsewhere) by omitting installDir.
  4. Fix typos in the configured path; verify it is absolute and not a UNC/network path.

Example fix

// before
installNasiko({ installDir: '/mnt/ghostdrive/nasiko/bin', yes: true })
// after
fs.mkdirSync('/mnt/real-drive/nasiko', { recursive: true })
installNasiko({ installDir: '/mnt/real-drive/nasiko/bin', yes: true })
Defensive patterns

Strategy: validation

Validate before calling

function installDirHasAncestor(dir) {
  let cur = path.resolve(dir)
  while (!fs.existsSync(cur)) {
    const parent = path.dirname(cur)
    if (parent === cur) return false
    cur = parent
  }
  return true
}
if (!installDirHasAncestor('/mnt/ghost/nasiko/bin')) throw new Error('create a real base directory first')

Type guard

const isNonRootExistingAncestor = (dir) => {
  let cur = path.resolve(dir)
  while (!fs.existsSync(cur)) {
    const p = path.dirname(cur)
    if (p === cur) return false
    cur = p
  }
  return cur !== path.parse(cur).root
}

Try / catch

try {
  await installNasiko({ installDir: dir, yes: true })
} catch (e) {
  if (e.message.includes('no resolvable filesystem ancestor')) {
    fs.mkdirSync(dir, { recursive: true })
    return installNasiko({ installDir: dir, yes: true })
  }
  throw e
}

Prevention

When it happens

Trigger: 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).

Common situations: 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.

Related errors


AI-assisted analysis of affaan-m/ECC@8321021c54 (2026-09-16). Data as JSON: /api/errors/843c96b0e19364b6. Report an issue: GitHub.

Appendix: source

Thrown at scripts/lib/nasiko-release.js:177

}

function defaultInstallDirectory(normalized, environment = process.env, homeDirectory = os.homedir()) {
  if (normalized.os === 'windows') {
    if (!environment.LOCALAPPDATA) throw new Error('LOCALAPPDATA is required on Windows.');
    return path.join(environment.LOCALAPPDATA, 'nasiko', 'bin');
  }
  return path.join(homeDirectory, '.local', 'bin');
}

function validateInstallDirectory(directory) {
  if (typeof directory !== 'string' || directory.includes('\0') || !path.isAbsolute(directory)) throw new Error('Nasiko install directory must be an absolute path.');
  if (/^(?:\\\\|\\\\\?\\|\\\\\.\\)/.test(directory)) throw new Error('Nasiko install directory must be on a local filesystem.');
  const resolved = path.resolve(directory);
  if (resolved === path.parse(resolved).root) throw new Error('Nasiko cannot install directly into a filesystem root.');
  let ancestor = resolved;
  while (!fs.existsSync(ancestor)) {
    const parent = path.dirname(ancestor);
    if (parent === ancestor) throw new Error('Nasiko install directory has no resolvable filesystem ancestor.');
    ancestor = parent;
  }
  const canonical = fs.realpathSync(ancestor);
  return path.join(canonical, path.relative(ancestor, resolved));
}

function assertPrivateInstallDirectory(directory) {
  const stats = fs.lstatSync(directory);
  if (!stats.isDirectory() || stats.isSymbolicLink()) throw new Error('Nasiko install directory must be a real directory, not a symlink.');
  if (process.platform !== 'win32') {
    if (typeof process.getuid === 'function' && stats.uid !== process.getuid()) throw new Error('Nasiko install directory must be owned by the current user.');
    if ((stats.mode & 0o022) !== 0) throw new Error('Nasiko install directory must not be group- or world-writable.');
  }
}

function metadataPathFor(executable) { return path.join(path.dirname(executable), METADATA_FILENAME); }

function readBoundedRegularFile(filePath, maximumBytes) {

View on GitHub (pinned to 8321021c54)