different-ai/openwork · error

Workspace path not found: ${workspaceRoot}

Error message

Workspace path not found: ${workspaceRoot}

What it means

exportWorkspaceConfig checks that workspace.path exists on disk via stat before collecting files. If the directory is missing (or is a dangling path), it throws with the path interpolated, because there is nothing to archive.

Source

Thrown at apps/desktop/electron/workspace-archive.mjs:262

  return {
    version: 1,
    workspace: {
      name: path.basename(targetDir) || "Workspace",
      createdAt: nowMs(),
      preset,
    },
    authorizedRoots: [targetDir],
    reload: null,
  };
}

export async function exportWorkspaceConfig({ workspace, outputPath }) {
  if (!workspace?.path || workspace.workspaceType === "remote") {
    throw new Error("Workspace export is only supported for local workspaces");
  }
  const workspaceRoot = workspace.path;
  if (!(await pathExists(workspaceRoot))) {
    throw new Error(`Workspace path not found: ${workspaceRoot}`);
  }

  const { entries, excluded } = await collectWorkspaceEntries(workspaceRoot);
  if (entries.length === 0) throw new Error("No workspace config files found to export");

  const files = [];
  const included = [];
  for (const entry of entries) {
    files.push({ name: entry.rel, data: await readFile(entry.absolute) });
    included.push(entry.rel);
  }
  files.push({
    name: "manifest.json",
    data: `${JSON.stringify({
      version: 1,
      createdAtMs: nowMs(),
      workspace: { id: workspace.id, name: workspace.name, path: workspace.path },
      included,

View on GitHub (pinned to 2b7df46e8a)

Solutions

  1. Verify the path exists with `ls <path>` and fix workspace.path to the real directory
  2. Recreate or re-clone the workspace at the recorded path
  3. Remove the stale workspace entry and register the workspace again
  4. Check mount/permission issues if the directory should exist (network drives, sandboxing)

Example fix

// before
await exportWorkspaceConfig({ workspace: { path: '/Users/me/projects/old-name', workspaceType: 'local' } })
// after
await exportWorkspaceConfig({ workspace: { path: '/Users/me/projects/new-name', workspaceType: 'local' } })
Defensive patterns

Strategy: validation

Validate before calling

import { stat } from 'node:fs/promises';
async function workspacePathExists(ws) {
  if (!ws?.path) return false;
  try { await stat(ws.path); return true; } catch { return false; }
}

Type guard

function hasExistingLocalPath(ws, exists) {
  return typeof ws?.path === 'string' && exists === true;
}

Try / catch

try {
  await exportWorkspaceConfig({ workspace });
} catch (err) {
  if (err.message.startsWith('Workspace path not found')) {
    // prompt user to fix/recreate the workspace directory
  } else throw err;
}

Prevention

When it happens

Trigger: Calling exportWorkspaceConfig where workspace.path points to a deleted, moved, or unmounted directory, or contains a typo, or the process lacks permissions so stat fails.

Common situations: Workspace folder deleted while the app still lists it; external drive/network mount offline; project directory renamed on disk; stale workspace registry entry after a cleanup.

Understand the failure class

Background: "File not found" and ENOENT errors: why libraries can't find a file that should exist — this error's family across 50 libraries.

Related errors


AI-assisted analysis of different-ai/openwork@2b7df46e8a (2026-09-01). Data as JSON: /api/errors/40dc56c22ddd9740. Report an issue: GitHub.