{"record":{"id":"b36e217a2cee72b9","repo":"stablyai/orca","slug":"symlink-not-allowed-in-basename-srcpath","errorCode":null,"errorMessage":"Symlink not allowed in '${basename(srcPath)}'","messagePattern":"Symlink not allowed in '(.+?)'","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"src/main/ipc/filesystem-mutations.ts","lineNumber":715,"sourceCode":"    if (statResult.isDirectory()) {\n      await recursiveCopyDir(srcPath, dstPath)\n      continue\n    }\n    if (!statResult.isFile()) {\n      throw new Error(`Unsupported file type in '${entry.name}'`)\n    }\n    await copyLocalFileNoFollow(srcPath, dstPath, statResult)\n  }\n}\n\nasync function copyLocalFileNoFollow(\n  srcPath: string,\n  dstPath: string,\n  statResult?: Awaited<ReturnType<typeof lstat>>\n): Promise<void> {\n  const beforeOpenStat = statResult ?? (await lstat(srcPath))\n  if (beforeOpenStat.isSymbolicLink()) {\n    throw new Error(`Symlink not allowed in '${basename(srcPath)}'`)\n  }\n  if (!beforeOpenStat.isFile()) {\n    throw new Error(`Unsupported file type in '${basename(srcPath)}'`)\n  }\n\n  let destinationCreated = false\n  const sourceHandle = await open(srcPath, constants.O_RDONLY | (constants.O_NOFOLLOW ?? 0))\n  let destinationHandle: Awaited<ReturnType<typeof open>> | null = null\n  try {\n    const openedStat = await sourceHandle.stat()\n    if (\n      !openedStat.isFile() ||\n      (typeof beforeOpenStat.size === 'number' && openedStat.size !== beforeOpenStat.size) ||\n      (typeof beforeOpenStat.ino === 'number' &&\n        beforeOpenStat.ino !== 0 &&\n        openedStat.ino !== 0 &&\n        openedStat.ino !== beforeOpenStat.ino) ||\n      (typeof beforeOpenStat.dev === 'number' &&","sourceCodeStart":697,"sourceCodeEnd":733,"githubUrl":"https://github.com/stablyai/orca/blob/1136503c6a231a16dce8f921f6fadb63d181e8db/src/main/ipc/filesystem-mutations.ts#L697-L733","documentation":"Thrown in copyLocalFileNoFollow during local import of a single file. The pre-open lstat (beforeOpenStat) detects the source path is a symbolic link. Local import policy forbids symlinks, so the copy aborts before opening the source handle.","triggerScenarios":"Importing a single top-level source file that is itself a symlink. The lstat on the resolved source path returns isSymbolicLink() true, and the function rejects it immediately.","commonSituations":"Dropping a symlinked file into the import target. Importing a file that is a symlink to a shared config or dotfile. A file manager creates a symlink instead of copying, and the user imports it.","solutions":["Replace the symlink with a real copy of the target file before importing.","Resolve the symlink manually with `readlink -f` and import the resolved target path instead.","Use `cp -L` to create a dereferenced copy, then import that copy."],"exampleFix":"// before: import /shortcut/config.json -> /real/config.json (symlink)\n// after: dereference and import the real file\n//   cp -L /shortcut/config.json /tmp/config.json\n//   import /tmp/config.json","handlingStrategy":"type-guard","validationCode":"const { lstat } = await import('node:fs/promises')\n\nasync function assertNotSymlink(filePath: string): Promise<void> {\n  const st = await lstat(filePath)\n  if (st.isSymbolicLink()) {\n    throw new Error(`${filePath} is a symlink — dereference or remove before importing`)\n  }\n}","typeGuard":"async function isRegularFile(filePath: string): Promise<boolean> {\n  const { lstat } = await import('node:fs/promises')\n  try {\n    const st = await lstat(filePath)\n    return st.isFile() // false for symlinks, dirs, special files\n  } catch {\n    return false\n  }\n}","tryCatchPattern":"try {\n  await importLocalSource(sourcePath, destDir)\n} catch (error) {\n  if (error instanceof Error && error.message.startsWith('Symlink not allowed')) {\n    showUserError(`${error.message} — replace with a real file copy.`)\n    return\n  }\n  throw error\n}","preventionTips":["Check single-file sources with `test -L <path>` or `readlink <path>` before importing.","Use `cp -L` to dereference symlinks into real copies before importing.","In file pickers, filter out symlinks from selectable entries."],"tags":["symlink","filesystem","local-import","security","ipc"],"backgroundTag":null,"analyzedSha":"1136503c6a231a16dce8f921f6fadb63d181e8db","analyzedAt":"2026-08-12T23:15:58.167Z","schemaVersion":2},"datasetVersion":"2026-08-12T23:17:12.415Z"}