{"record":{"id":"5ea1b260f529ded9","repo":"affaan-m/ECC","slug":"nasiko-install-directory-must-be-on-a-local-filesy","errorCode":null,"errorMessage":"Nasiko install directory must be on a local filesystem.","messagePattern":"Nasiko install directory must be on a local filesystem\\.","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"scripts/lib/nasiko-release.js","lineNumber":171,"sourceCode":"      response.on('end', () => resolve(Buffer.concat(chunks)));\n      response.on('error', reject);\n    });\n    request.setTimeout(options.timeoutMs || 15000, () => request.destroy(new Error('Nasiko registry request timed out.')));\n    request.on('error', reject);\n  });\n}\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.');","sourceCodeStart":153,"sourceCodeEnd":189,"githubUrl":"https://github.com/affaan-m/ECC/blob/8321021c54d670126ce3b2969d5deb880b4b0c2a/scripts/lib/nasiko-release.js#L153-L189","documentation":"validateInstallDirectory rejects directories whose path begins with a Windows UNC prefix (\\\\, \\\\?\\, or \\\\.\\) because installs must land on a local filesystem, not a network share or device path. The regex matches these prefixes and throws this error.","triggerScenarios":"Passing an install directory like \\\\\\\\server\\\\share\\\\nasiko, \\\\\\\\?\\\\C\\\\... (long-path form), or \\\\\\\\.\\\\device... to installDirectory, parseMutationArguments, candidate, or parseStatusArguments — typically on Windows or with Windows-style paths.","commonSituations":"Corporate setups that home profiles or tool directories on network shares (SMB); users mapping a drive to a share and pasting the UNC path; Docker/CI volumes expressed as UNC paths on Windows.","solutions":["Use a local-disk directory (e.g. C:\\\\Users\\\\me\\\\AppData\\\\Local\\\\nasiko\\\\bin).","Map the share to a drive letter only if the underlying target is local — otherwise move the install to the local disk.","Update config/scripts that hardcode a UNC path to a local absolute path.","If the long-path \\\\\\\\?\\ form is needed for a local path, use the plain absolute form instead."],"exampleFix":"// before\nawait installDirectory({ os: 'windows', dir: '\\\\\\\\\\\\\\\\fileserver\\\\\\\\tools\\\\\\\\nasiko' });\n// after\nawait installDirectory({ os: 'windows', dir: 'C:\\\\Users\\\\me\\\\AppData\\\\Local\\\\nasiko\\\\bin' });","handlingStrategy":"validation","validationCode":"if (/^(?:\\\\\\\\|\\\\\\\\\\?\\\\|\\\\\\\\\\.\\\\)/.test(dir)) throw new Error('Install dir must be a local path, not a UNC/device path.');","typeGuard":"const isLocalPath = (d) => typeof d === 'string' && !/^(?:\\\\\\\\|\\\\\\\\\\?\\\\|\\\\\\\\\\.\\\\)/.test(d);","tryCatchPattern":"try { await installDirectory({ dir }); } catch (err) { if (err.message.includes('local filesystem')) throw new Error('Use a local disk path instead of ' + dir); throw err; }","preventionTips":["Default install dirs to the local user profile, never network shares","Reject UNC prefixes in your wrapper's input validation","For long local paths use a normal absolute path, not the \\\\\\\\?\\ form","Audit CI volumes/mounts on Windows so tools install to local disk"],"tags":["path","windows","unc","validation"],"backgroundTag":"invalid-argument-value","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"}