stablyai/orca · error · Error

Computer screenshot temp path is not owned by the current us

Error message

Computer screenshot temp path is not owned by the current user: ${outputDir}

What it means

Thrown by computerScreenshotTempDir() when lstatSync shows the directory is not owned by the current process uid (checked only where process.getuid exists, i.e. POSIX). The 0700 directory would otherwise protect the owner's files, but if another uid owns it that protection does not apply to the running agent, leaking screenshots or allowing tampering. This is a TOCTOU-style ownership guard complementing the directory/symlink check.

Source

Thrown at src/cli/computer-format.ts:113

    // data when disk, permissions, or path validation would otherwise fail --json.
    return response
  }
}

const COMPUTER_SCREENSHOT_TTL_MS = 24 * 60 * 60 * 1000
const COMPUTER_SCREENSHOT_CLEANUP_INTERVAL_MS = 60 * 60 * 1000
const COMPUTER_SCREENSHOT_CLEANUP_MARKER = '.last-cleanup'

function computerScreenshotTempDir(): string {
  const outputDir =
    process.env.ORCA_COMPUTER_SCREENSHOT_TMPDIR || join(tmpdir(), 'orca-computer-use')
  mkdirSync(outputDir, { recursive: true, mode: 0o700 })
  const stat = lstatSync(outputDir)
  if (!stat.isDirectory() || stat.isSymbolicLink()) {
    throw new Error(`Unsafe computer screenshot temp path: ${outputDir}`)
  }
  if (typeof process.getuid === 'function' && stat.uid !== process.getuid()) {
    throw new Error(`Computer screenshot temp path is not owned by the current user: ${outputDir}`)
  }
  chmodSync(outputDir, 0o700)
  return outputDir
}

function cleanupComputerScreenshots(outputDir: string): void {
  const now = Date.now()
  const markerPath = join(outputDir, COMPUTER_SCREENSHOT_CLEANUP_MARKER)
  try {
    // Why: agents can call computer-use CLI commands in loops; a marker keeps
    // temp cleanup from becoming a synchronous directory scan per screenshot.
    if (statSync(markerPath).mtimeMs > now - COMPUTER_SCREENSHOT_CLEANUP_INTERVAL_MS) {
      return
    }
  } catch {
    // Missing or unreadable marker means this process should attempt cleanup.
  }

View on GitHub (pinned to 1136503c6a)

Solutions

  1. Delete the existing directory so the current user recreates it with correct ownership: `rm -rf <path>`.
  2. Run the Orca process under the same uid that owns the target directory.
  3. Set ORCA_COMPUTER_SCREENSHOT_TMPDIR to a per-user path under your home or XDG_RUNTIME_DIR.

Example fix

# before: dir owned by root
ls -ld /tmp/orca-computer-use   # drwx------ root root

# after
sudo rm -rf /tmp/orca-computer-use  # let current user recreate
Defensive patterns

Strategy: validation

Validate before calling

import { lstatSync } from 'node:fs'

function assertOwnedByCurrentUid(p: string): void {
  if (typeof process.getuid === 'function') {
    const st = lstatSync(p)
    if (st.uid !== process.getuid()) {
      throw new Error(`${p} owned by uid ${st.uid}, expected ${process.getuid()}`)
    }
  }
}

Type guard

function isOwnedByCurrentUid(p: string): boolean {
  try {
    return typeof process.getuid !== 'function' || lstatSync(p).uid === process.getuid()
  } catch {
    return false
  }
}

Prevention

When it happens

Trigger: The screenshot temp dir exists but is owned by a different uid than process.getuid() — e.g. created by root or another user before the current process ran, or after a sudo/non-sudo mixup.

Common situations: Running Orca once under sudo then again as a normal user, a system service creating the dir as root, multi-user machines, or containers where the uid differs between image-build and runtime.

Related errors


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