{"record":{"id":"40dc56c22ddd9740","repo":"different-ai/openwork","slug":"workspace-path-not-found-workspaceroot","errorCode":null,"errorMessage":"Workspace path not found: ${workspaceRoot}","messagePattern":"Workspace path not found: (.+?)","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"apps/desktop/electron/workspace-archive.mjs","lineNumber":262,"sourceCode":"  return {\n    version: 1,\n    workspace: {\n      name: path.basename(targetDir) || \"Workspace\",\n      createdAt: nowMs(),\n      preset,\n    },\n    authorizedRoots: [targetDir],\n    reload: null,\n  };\n}\n\nexport async function exportWorkspaceConfig({ workspace, outputPath }) {\n  if (!workspace?.path || workspace.workspaceType === \"remote\") {\n    throw new Error(\"Workspace export is only supported for local workspaces\");\n  }\n  const workspaceRoot = workspace.path;\n  if (!(await pathExists(workspaceRoot))) {\n    throw new Error(`Workspace path not found: ${workspaceRoot}`);\n  }\n\n  const { entries, excluded } = await collectWorkspaceEntries(workspaceRoot);\n  if (entries.length === 0) throw new Error(\"No workspace config files found to export\");\n\n  const files = [];\n  const included = [];\n  for (const entry of entries) {\n    files.push({ name: entry.rel, data: await readFile(entry.absolute) });\n    included.push(entry.rel);\n  }\n  files.push({\n    name: \"manifest.json\",\n    data: `${JSON.stringify({\n      version: 1,\n      createdAtMs: nowMs(),\n      workspace: { id: workspace.id, name: workspace.name, path: workspace.path },\n      included,","sourceCodeStart":244,"sourceCodeEnd":280,"githubUrl":"https://github.com/different-ai/openwork/blob/2b7df46e8ae1517d64c896c7793d2d52ec845669/apps/desktop/electron/workspace-archive.mjs#L244-L280","documentation":"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.","triggerScenarios":"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.","commonSituations":"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.","solutions":["Verify the path exists with `ls <path>` and fix workspace.path to the real directory","Recreate or re-clone the workspace at the recorded path","Remove the stale workspace entry and register the workspace again","Check mount/permission issues if the directory should exist (network drives, sandboxing)"],"exampleFix":"// before\nawait exportWorkspaceConfig({ workspace: { path: '/Users/me/projects/old-name', workspaceType: 'local' } })\n// after\nawait exportWorkspaceConfig({ workspace: { path: '/Users/me/projects/new-name', workspaceType: 'local' } })","handlingStrategy":"validation","validationCode":"import { stat } from 'node:fs/promises';\nasync function workspacePathExists(ws) {\n  if (!ws?.path) return false;\n  try { await stat(ws.path); return true; } catch { return false; }\n}","typeGuard":"function hasExistingLocalPath(ws, exists) {\n  return typeof ws?.path === 'string' && exists === true;\n}","tryCatchPattern":"try {\n  await exportWorkspaceConfig({ workspace });\n} catch (err) {\n  if (err.message.startsWith('Workspace path not found')) {\n    // prompt user to fix/recreate the workspace directory\n  } else throw err;\n}","preventionTips":["Stat workspace.path before offering export","Prune stale workspace entries when their directories vanish","Watch for unmounted network/external volumes"],"tags":["filesystem","path-not-found","workspace"],"backgroundTag":"file-not-found","analyzedSha":"2b7df46e8ae1517d64c896c7793d2d52ec845669","analyzedAt":"2026-09-01T07:59:23.713Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-08T10:18:20.063Z"}