stablyai/orca · warning · RuntimeUploadSymlinkError

Symlink not allowed in '${childRelativePath}'

Error message

Symlink not allowed in '${childRelativePath}'

What it means

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.

Source

Thrown at src/main/ipc/filesystem-mutations.ts:549

        `Symlink not allowed in '${normalizeRelativeUploadPath(relative(rootPath, dirPath))}'`
      )
    }
    if (!dirStat.isDirectory()) {
      throw new Error(
        `Unsupported file type in '${normalizeRelativeUploadPath(relative(rootPath, dirPath))}'`
      )
    }
    await assertRealPathInsideRoot(
      rootRealPath,
      dirPath,
      normalizeRelativeUploadPath(relative(rootPath, dirPath))
    )
    const dirEntries = await readdir(dirPath, { withFileTypes: true })
    for (const entry of dirEntries) {
      const childPath = join(dirPath, entry.name)
      const childRelativePath = normalizeRelativeUploadPath(relative(rootPath, childPath))
      if (entry.isSymbolicLink()) {
        throw new RuntimeUploadSymlinkError(`Symlink not allowed in '${childRelativePath}'`)
      }
      if (entry.isDirectory()) {
        entries.push({ relativePath: childRelativePath, kind: 'directory' })
        await visit(childPath)
        continue
      }
      if (!entry.isFile()) {
        throw new Error(`Unsupported file type in '${childRelativePath}'`)
      }
      const stagedFile = await stageFileEntry(childPath, childRelativePath, {
        rootRealPath,
        totalBytesBefore: totalBytes
      })
      totalBytes += stagedFile.byteLength
      entries.push(stagedFile.entry)
    }
  }

View on GitHub (pinned to 1136503c6a)

Solutions

  1. Remove or un-symlink the child entries in the source tree before staging.
  2. Replace symlinks with copies of their targets if the content is needed in the upload.
  3. Treat the skipped result as expected for symlinked sources and inform the user.
Defensive patterns

Strategy: try-catch

Validate before calling

// Pre-scan for symlinked children before staging a directory
import { readdir } from 'node:fs/promises'
async function hasSymlinkChild(dir: string): Promise<boolean> {
  for (const e of await readdir(dir, { withFileTypes: true })) {
    if (e.isSymbolicLink()) return true
    if (e.isDirectory() && await hasSymlinkChild(joinPath(dir, e.name))) return true
  }
  return false
}

Try / catch

const res = await stageOneSourceForRuntimeUpload(src)
if (res.status === 'skipped' && res.reason === 'symlink') {
  // inform the user that a symlinked child blocked staging; offer cleanup
}

Prevention

When it happens

Trigger: 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.

Common situations: Monorepo with symlinked packages; symlinked config files (e.g. linked .env); build tooling that creates symlinked assets; user-selected tree containing shortcuts/links.

Related errors


AI-assisted analysis of stablyai/orca@1136503c6a (2026-08-12). Data as JSON: /api/errors/27e18d198c9b8757. Report an issue: GitHub.