CherryHQ/cherry-studio · error · Error

Session workspace is unavailable: ${workspaceRoot}

Error message

Session workspace is unavailable: ${workspaceRoot}

What it means

Thrown by resolveWorkspaceFile() when realpath(workspaceRoot) fails with ENOENT or ENOTDIR. Unlike the per-file 'File not found' error, this specifically indicates the workspace root directory itself is gone. The comment in the source explains: a bare ENOENT naming the root would read like 'your file_path is wrong', so this is wrapped to tell the agent the session workspace itself is unavailable, preventing wasted retries on alternative file paths.

Source

Thrown at src/main/ai/channels/security/WorkspaceFileGuard.ts:33

 * inside it. `realpath` defeats `../` and symlink escape; reading happens on a single
 * fd over the canonical path so the stat/size check and the read see the same inode.
 *
 * This is defense-in-depth against traversal mistakes and prompt injection picking a
 * wrong path — not a sandbox against an agent with code execution (which can already
 * read arbitrary files and exfiltrate them as message text). See #16566.
 */
export async function resolveWorkspaceFile(workspaceRoot: string, userPath: string): Promise<FileAttachment> {
  const requested = path.resolve(workspaceRoot, userPath)

  let realRoot: string
  try {
    realRoot = await realpath(workspaceRoot)
  } catch (error) {
    // The root is a caller invariant, but if the session workspace is gone a bare ENOENT
    // naming the root reads like "your file_path is wrong" — wrap it so the agent doesn't
    // waste retries on other paths.
    if (isErrnoException(error) && (error.code === 'ENOENT' || error.code === 'ENOTDIR')) {
      throw new Error(`Session workspace is unavailable: ${workspaceRoot}`)
    }
    throw error
  }

  let realTarget: string
  try {
    realTarget = await realpath(requested)
  } catch (error) {
    if (isErrnoException(error) && (error.code === 'ENOENT' || error.code === 'ENOTDIR')) {
      throw new Error(`File not found in workspace: ${userPath}`)
    }
    throw error
  }

  if (realTarget !== realRoot && !realTarget.startsWith(realRoot + path.sep)) {
    throw new Error(`Path is outside the workspace: ${userPath}`)
  }

View on GitHub (pinned to 726446b54c)

Solutions

  1. Verify the session workspace directory still exists at the path given by workspaceRoot — if it was cleaned, recreate it or start a new session.
  2. If this is a crash-restart path, ensure the session lifecycle recreates the workspace directory before rehydrating agent state.
  3. If running on a temp directory, increase the OS temp-cleanup interval or move workspaces to a stable application-managed path via application.getPath().
Defensive patterns

Strategy: try-catch

Validate before calling

import { exists } from '@main/utils/file'

// Check workspace exists before resolving files
const workspaceExists = await exists(workspaceRoot)
if (!workspaceExists) {
  throw new Error(`Workspace not found, recreating or starting new session: ${workspaceRoot}`)
}

Try / catch

try {
  return await resolveWorkspaceFile(workspaceRoot, userPath)
} catch (error) {
  if (error instanceof Error && error.message.startsWith('Session workspace is unavailable:')) {
    // The workspace itself is gone — no retry on alternative paths will help
    logger.error('Session workspace missing', { workspaceRoot })
    throw new Error('Session workspace was deleted. Start a new session.')
  }
  throw error
}

Prevention

When it happens

Trigger: Called from agent document tools (cherryDocumentTools.ts:84, cherryAutonomyTools.ts:436) when an agent attempts to read a workspace file but the workspace directory was deleted, unmounted, or the session's workspacePath was never created. This is a caller-invariant violation: the workspace root is expected to exist for the entire session lifetime.

Common situations: The session workspace temp directory was cleaned by an OS temp-reaper or manual cleanup while the agent was still running; a crash-restart scenario where the workspace path was persisted but the directory was not recreated; the workspace was on a removable drive that was ejected; a workspace creation race where the agent started before the directory was fully set up.

Related errors


AI-assisted analysis of CherryHQ/cherry-studio@726446b54c (2026-08-12). Data as JSON: /api/errors/b007c54d8d0054b9. Report an issue: GitHub.