{"record":{"id":"25337bc03fe936b0","repo":"different-ai/openwork","slug":"no-local-workspace-is-available","errorCode":null,"errorMessage":"No local workspace is available","messagePattern":"No local workspace is available","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"apps/desktop/electron/automation-runner.mjs","lineNumber":145,"sourceCode":" *\n * A pinned workspace must exist locally: running the Automation in whatever\n * workspace happens to be active would silently retarget it, which is the\n * exact bug pinning exists to prevent. Unpinned (legacy) assignments keep the\n * historical active-workspace fallback.\n */\nexport function resolveAssignmentWorkspace(listed, pinnedWorkspaceId) {\n  const workspaces = Array.isArray(listed?.items) ? listed.items : []\n  if (pinnedWorkspaceId) {\n    const pinned = workspaces.find((item) => item?.id === pinnedWorkspaceId)\n    if (!pinned?.id) {\n      const error = new Error(`The Automation's pinned workspace is not available on this desktop`)\n      Object.defineProperty(error, \"code\", { value: \"execution_runtime_unavailable\" })\n      throw error\n    }\n    return pinned\n  }\n  const workspace = workspaces.find((item) => item?.id === listed?.activeId) ?? workspaces[0]\n  if (!workspace?.id) throw new Error(\"No local workspace is available\")\n  return workspace\n}\n\n/** Runs the assignment as a normal visible local OpenWork thread. */\nexport async function executeDesktopAutomation(assignment, options) {\n  const local = await options.getLocalRuntime()\n  if (!local?.baseUrl || !local?.token) throw new Error(\"The desktop runtime is unavailable\")\n  const localRequest = (requestPath, request = {}) => requestJson(\n    options.fetchImpl ?? fetch,\n    local.baseUrl,\n    local.token,\n    requestPath,\n    { ...request, signal: options.signal },\n  )\n  const listed = await localRequest(\"/workspaces\")\n  const workspace = resolveAssignmentWorkspace(listed, assignment.workspaceId ?? null)\n  const workspaceId = String(workspace.id)\n  const client = createWorkspaceSessionClient(local, workspaceId, options.fetchImpl ?? fetch)","sourceCodeStart":127,"sourceCodeEnd":163,"githubUrl":"https://github.com/different-ai/openwork/blob/2b7df46e8ae1517d64c896c7793d2d52ec845669/apps/desktop/electron/automation-runner.mjs#L127-L163","documentation":"resolveAssignmentWorkspace picks the active workspace (or first item) from the local runtime's workspace list to run a Desktop Automation assignment. If the pinned/execution runtime is fine but the list has no workspace with a usable id, there is no local workspace to execute in, so it throws with code path 'no local workspace'.","triggerScenarios":"executeDesktopAutomation calls resolveAssignmentWorkspace; the /workspaces listing returns an empty array or items all lack `id`, and the fallback `workspaces[0]` is undefined/no-id.","commonSituations":"Fresh install where no workspace was ever created; all workspaces deleted; automation scheduled before first-run onboarding completed; corrupted workspace state file.","solutions":["Create at least one local workspace in the OpenWork app before scheduling automation","Re-run onboarding/workspace creation so the server has a workspace","Check /workspaces response to confirm items exist with ids","Restore or reset corrupted workspace state"],"exampleFix":"// before: scheduling automation on a machine with zero workspaces\nawait scheduleAssignment(assignment); // -> No local workspace is available\n// after: ensure a workspace exists first\nconst listed = await requestJson(fetch, baseUrl, token, \"/workspaces\");\nif (!listed?.items?.length) await createWorkspace({ name: \"Default\" });\nawait scheduleAssignment(assignment);","handlingStrategy":"validation","validationCode":"const listed = await requestJson(fetch, baseUrl, token, \"/workspaces\");\nconst items = Array.isArray(listed?.items) ? listed.items : [];\nif (!items.some(w => typeof w?.id === \"string\" && w.id)) {\n  throw new Error(\"Create a local workspace before running automation\");\n}","typeGuard":"function hasUsableWorkspace(listed) {\n  const items = Array.isArray(listed?.items) ? listed.items : [];\n  return items.some(w => typeof w?.id === \"string\" && w.id.length > 0);\n}","tryCatchPattern":"try {\n  await runAssignment(assignment);\n} catch (err) {\n  if (err.message === \"No local workspace is available\") {\n    await createDefaultWorkspace();\n    await runAssignment(assignment);\n  } else throw err;\n}","preventionTips":["Provision a default workspace during first-run onboarding","Never allow scheduling automations while zero workspaces exist","Validate /workspaces output shape before executing assignments","Alert the user when workspace count drops to zero"],"tags":["workspace","automation","empty-state"],"backgroundTag":"no-workspace-available","analyzedSha":"2b7df46e8ae1517d64c896c7793d2d52ec845669","analyzedAt":"2026-09-01T07:59:23.713Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-08T10:18:20.063Z"}