affaan-m/ECC · error
Nasiko cannot install directly into a filesystem root.
Error message
Nasiko cannot install directly into a filesystem root.
What it means
validateInstallDirectory resolves the requested path and refuses a path equal to the filesystem root (e.g. / on POSIX, C:\ on Windows). Installing directly into a root would scatter binaries and directories at the top level of a volume, so it is blocked. A non-root error ('no resolvable filesystem ancestor') exists for the opposite case of a path whose ancestors are all unresolvable.
Solutions
- Choose a real subdirectory, e.g. /usr/local/bin or C:\\Users\\me\\nasiko\\bin.
- Fix the templating/script bug where the directory component was dropped and only the root remained.
- Add a guard in your wrapper that rejects root paths before delegating to the library.
- If a config file specifies the root, edit it to a concrete absolute subpath.
Example fix
// before
const dir = process.env.NASIKO_PREFIX || '/';
await installDirectory({ dir });
// after
const dir = process.env.NASIKO_PREFIX || '/usr/local/bin';
if (path.resolve(dir) === path.parse(path.resolve(dir)).root) throw new Error('Refusing filesystem root install dir.');
await installDirectory({ dir }); Defensive patterns
Strategy: validation
Validate before calling
const r = path.resolve(dir); if (r === path.parse(r).root) throw new Error('Install dir must be a subdirectory, not a filesystem root.'); Type guard
const isNonRootDir = (d) => { const r = path.resolve(d); return r !== path.parse(r).root; }; Try / catch
try { await installDirectory({ dir }); } catch (err) { if (err.message.includes('filesystem root')) throw new Error('Refusing root install; pass a concrete subdirectory.'); throw err; } Prevention
- Never default install paths to '/' or a bare drive letter
- Check template expansions so an empty suffix cannot collapse the path to root
- Validate that the chosen dir resolves to more than just a root component
- Prefer standard locations like ~/.local/bin or %LOCALAPPDATA%\\nasiko\\bin
When it happens
Trigger: Calling installDirectory, parseMutationArguments, candidate, or parseStatusArguments with --dir / or --dir C:\\ (or any drive root), so path.resolve(dir) === path.parse(resolved).root.
Common situations: CLI users typing '--dir /' as shorthand for 'system-wide'; scripts parameterized with an empty suffix (prefix + '' collapses to root); config defaulting to a bare drive letter on Windows.
Understand the failure class
Background: "Must be a positive integer", "Invalid value", "Unsupported": the invalid-argument-value error family, when a library rejects the value you pass — this error's family across 35 libraries.
Related errors
- output bundle root must be a directory
- output root must be a directory
- all overlays must be readable local files
- all takes must be readable local files
- artifact path must stay beneath output root
AI-assisted analysis of affaan-m/ECC@8321021c54 (2026-09-16).
Data as JSON: /api/errors/c8537e5f10d4bf02.
Report an issue: GitHub.
Appendix: source
Thrown at scripts/lib/nasiko-release.js:173
});
request.setTimeout(options.timeoutMs || 15000, () => request.destroy(new Error('Nasiko registry request timed out.')));
request.on('error', reject);
});
}
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.');
}
}View on GitHub (pinned to 8321021c54)