{"record":{"id":"8f0272dc8a9567af","repo":"affaan-m/ECC","slug":"nasiko-install-directory-must-be-owned-by-the-curr","errorCode":null,"errorMessage":"Nasiko install directory must be owned by the current user.","messagePattern":"Nasiko install directory must be owned by the current user\\.","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"scripts/lib/nasiko-release.js","lineNumber":188,"sourceCode":"  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) {\n  const noFollow = fs.constants.O_NOFOLLOW;\n  const descriptor = fs.openSync(filePath, fs.constants.O_RDONLY | (noFollow || 0));\n  try {\n    const stats = fs.fstatSync(descriptor);\n    if (!stats.isFile() || stats.size <= 0 || stats.size > maximumBytes) return null;\n    if (!noFollow) {\n      const pathStats = fs.lstatSync(filePath);\n      if (pathStats.isSymbolicLink()\n        || pathStats.dev !== stats.dev\n        || pathStats.ino !== stats.ino\n        || pathStats.birthtimeMs !== stats.birthtimeMs) {","sourceCodeStart":170,"sourceCodeEnd":206,"githubUrl":"https://github.com/affaan-m/ECC/blob/8321021c54d670126ce3b2969d5deb880b4b0c2a/scripts/lib/nasiko-release.js#L170-L206","documentation":"On non-Windows platforms, the library checks that the install directory's owning UID matches process.getuid(). If the directory is owned by another user, it throws this error to prevent installing into a location another account controls (a privilege-escalation vector).","triggerScenarios":"installNasiko or uninstallNasiko where the install directory's lstat uid differs from the current user — e.g. installDir pointing at /usr/local/bin or another user's home directory while running as an unprivileged user.","commonSituations":"Trying to install system-wide (/usr/local/bin) without sudo or vice versa (running with sudo but dir owned by user); shared machines where a teammate created the directory; containers where HOME/user was remapped and the directory retains a different UID.","solutions":["Run the install as the user who owns the directory (matching UID).","Chown the directory to the current user: `sudo chown $(id -u):$(id -g) <dir>`.","Choose a different installDir owned by the current user (e.g. ~/.local/bin).","Avoid running the installer with sudo into user-owned paths; install per-user instead."],"exampleFix":"// before (directory owned by root)\nsudo mkdir -p /opt/nasiko/bin && nasiko install\n// after\nsudo chown -R \"$(id -u):$(id -g)\" /opt/nasiko/bin\nnasiko install --install-dir /opt/nasiko/bin --yes","handlingStrategy":"validation","validationCode":"const stats = fs.statSync(dir)\nif (typeof process.getuid === 'function' && stats.uid !== process.getuid()) {\n  throw new Error(`installDir owned by uid ${stats.uid}, not ${process.getuid()}`)\n}","typeGuard":null,"tryCatchPattern":"try {\n  await installNasiko({ installDir: dir, yes: true })\n} catch (e) {\n  if (e.message.includes('owned by the current user')) {\n    console.error(`Run: sudo chown $(id -u):$(id -g) ${dir} — or pick a user-owned installDir`)\n  }\n  throw e\n}","preventionTips":["Install per-user (~/.local/bin) rather than into system paths.","Never run installs with sudo into user-owned directories.","Check ownership with `ls -ld` before configuring a custom installDir.","In containers, ensure HOME and the install dir are created by the same user."],"tags":["permissions","ownership","security","unix"],"backgroundTag":"insufficient-permissions","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"}