{"record":{"id":"27e18d198c9b8757","repo":"stablyai/orca","slug":"symlink-not-allowed-in-childrelativepath","errorCode":null,"errorMessage":"Symlink not allowed in '${childRelativePath}'","messagePattern":"Symlink not allowed in '(.+?)'","errorType":"exception","errorClass":"RuntimeUploadSymlinkError","httpStatus":null,"severity":"warning","filePath":"src/main/ipc/filesystem-mutations.ts","lineNumber":549,"sourceCode":"        `Symlink not allowed in '${normalizeRelativeUploadPath(relative(rootPath, dirPath))}'`\n      )\n    }\n    if (!dirStat.isDirectory()) {\n      throw new Error(\n        `Unsupported file type in '${normalizeRelativeUploadPath(relative(rootPath, dirPath))}'`\n      )\n    }\n    await assertRealPathInsideRoot(\n      rootRealPath,\n      dirPath,\n      normalizeRelativeUploadPath(relative(rootPath, dirPath))\n    )\n    const dirEntries = await readdir(dirPath, { withFileTypes: true })\n    for (const entry of dirEntries) {\n      const childPath = join(dirPath, entry.name)\n      const childRelativePath = normalizeRelativeUploadPath(relative(rootPath, childPath))\n      if (entry.isSymbolicLink()) {\n        throw new RuntimeUploadSymlinkError(`Symlink not allowed in '${childRelativePath}'`)\n      }\n      if (entry.isDirectory()) {\n        entries.push({ relativePath: childRelativePath, kind: 'directory' })\n        await visit(childPath)\n        continue\n      }\n      if (!entry.isFile()) {\n        throw new Error(`Unsupported file type in '${childRelativePath}'`)\n      }\n      const stagedFile = await stageFileEntry(childPath, childRelativePath, {\n        rootRealPath,\n        totalBytesBefore: totalBytes\n      })\n      totalBytes += stagedFile.byteLength\n      entries.push(stagedFile.entry)\n    }\n  }\n","sourceCodeStart":531,"sourceCodeEnd":567,"githubUrl":"https://github.com/stablyai/orca/blob/1136503c6a231a16dce8f921f6fadb63d181e8db/src/main/ipc/filesystem-mutations.ts#L531-L567","documentation":"Thrown as RuntimeUploadSymlinkError by stageDirectoryEntries() when a child entry read via readdir(withFileTypes) is a symbolic link (entry.isSymbolicLink()). Like 1134 it is caught upstairs and turned into a skipped result, so a symlinked child fails the whole source's staging gracefully rather than uploading the link target.","triggerScenarios":"During stageDirectoryEntries, readdir returns a child Dirent that is a symlink (e.g. a symlinked file or subfolder inside the staged directory). The check runs per-entry, so any single symlinked child triggers it.","commonSituations":"Monorepo with symlinked packages; symlinked config files (e.g. linked .env); build tooling that creates symlinked assets; user-selected tree containing shortcuts/links.","solutions":["Remove or un-symlink the child entries in the source tree before staging.","Replace symlinks with copies of their targets if the content is needed in the upload.","Treat the skipped result as expected for symlinked sources and inform the user."],"exampleFix":null,"handlingStrategy":"try-catch","validationCode":"// Pre-scan for symlinked children before staging a directory\nimport { readdir } from 'node:fs/promises'\nasync function hasSymlinkChild(dir: string): Promise<boolean> {\n  for (const e of await readdir(dir, { withFileTypes: true })) {\n    if (e.isSymbolicLink()) return true\n    if (e.isDirectory() && await hasSymlinkChild(joinPath(dir, e.name))) return true\n  }\n  return false\n}","typeGuard":null,"tryCatchPattern":"const res = await stageOneSourceForRuntimeUpload(src)\nif (res.status === 'skipped' && res.reason === 'symlink') {\n  // inform the user that a symlinked child blocked staging; offer cleanup\n}","preventionTips":["Pre-scan dropped directories for symlinks and warn the user before staging.","Un-symlink children or replace them with copies of their targets.","Treat skipped/symlink results as expected for symlink-bearing trees."],"tags":["symlink","upload","runtime-upload","staging","skipped"],"backgroundTag":null,"analyzedSha":"1136503c6a231a16dce8f921f6fadb63d181e8db","analyzedAt":"2026-08-12T23:15:58.167Z","schemaVersion":2},"datasetVersion":"2026-08-12T23:17:12.415Z"}