{"record":{"id":"c624669b8f7b738f","repo":"sinelaw/fresh","slug":"workspace-creation-failed","errorCode":null,"errorMessage":"workspace creation failed","messagePattern":"workspace creation failed","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"crates/fresh-editor/plugins/orchestrator.ts","lineNumber":10459,"sourceCode":"    // Worktree by default (the dialog's default too); `runLocalCreate` demotes\n    // it to false on its own when the path isn't a git tree.\n    createWorktree: options.worktree ?? true,\n  });\n}\n\nasync function newWorkspace(\n  options: NewWorkspaceOptions = {},\n): Promise<AgentLaunchResult> {\n  // Before `specForNewWorkspace`, which rejects a bad host / missing path.\n  await yieldToCaller();\n  const spec = specForNewWorkspace(options);\n  const pendingId = await startPendingWorkspace(spec, { visit: options.visit ?? false });\n  const outcome = await awaitCreateOutcome(pendingId);\n  if (!outcome.ok) {\n    // Thrown, not returned: a failed create must reject the caller's promise\n    // (and so fail its script), not hand it a result object it might mistake\n    // for a workspace. The dock keeps the row for a human to retry or dismiss.\n    throw new Error(outcome.error || \"workspace creation failed\");\n  }\n  return {\n    workspaceId: outcome.workspaceId ?? \"\",\n    windowId: outcome.windowId ?? 0,\n    root: outcome.root ?? \"\",\n  };\n}\n\nfunction listWorkspaces(): WorkspaceSummary[] {\n  // Reconcile first: a workspace created seconds ago (by a script, or by\n  // the dialog) is only in the model once the host's window list has been\n  // folded in, and a caller listing right after creating should see it.\n  reconcileSessions();\n  const windows = editor.listWindows();\n  const activeId = editor.activeWindow();\n  return [...orchestratorSessions.values()].map((session) => {\n    const win = windows.find((w) => w.id === session.id);\n    const git = session.git?.info;","sourceCodeStart":10441,"sourceCodeEnd":10477,"githubUrl":"https://github.com/sinelaw/fresh/blob/67894ca5463dbd7a89bb31add4627c27d6b79d83/crates/fresh-editor/plugins/orchestrator.ts#L10441-L10477","documentation":"After the orchestrator starts a pending workspace via startPendingWorkspace, it awaits awaitCreateOutcome; if the creation outcome is not ok, the stored outcome.error is thrown (falling back to the generic 'workspace creation failed' when no specific message was recorded). The comment stresses the design: a failed create must reject the caller's promise — and thus fail its script — rather than return a result object that could be mistaken for a workspace. The dock keeps the row so a human can retry or dismiss.","triggerScenarios":"Calling the workspace-create API when the underlying create operation fails: the remote/local spawn fails, the backend reports an error outcome, or awaitCreateOutcome resolves with ok=false and no error message (yielding the generic fallback string).","commonSituations":"Backend process crashed or refused the create (port conflicts, resource limits); invalid spec that passed pre-validation but failed at spawn time; infrastructure issues on a remote host; a bug/timeout leaving the outcome without an error message so only the generic text appears.","solutions":["Check the editor dock/log for the failing workspace row and any more specific error recorded there, since the thrown message may be the generic fallback.","Retry the create after fixing the underlying cause (free resources, fix host connectivity).","Inspect the spec returned by the builder (host/path/identity) for values that pass validation but fail at runtime.","If the generic message appears repeatedly with no detail, capture editor.debug/error logs around awaitCreateOutcome to find the real cause."],"exampleFix":"// before\nconst ws = await orchestrator.createWorkspace(options); // rejects with 'workspace creation failed'\n// after\ntry {\n  const ws = await orchestrator.createWorkspace(options);\n} catch (e) {\n  editor.error(`create failed: ${e}; check dock row and logs for detail`);\n  // surface outcome.error or retry with corrected options\n}","handlingStrategy":"try-catch","validationCode":"// pre-flight: make sure the spec's inputs are sound before starting the pending workspace\nif (spec.projectPath && !fs.existsSync(spec.projectPath)) throw new Error(\"path missing before create\");","typeGuard":"function isCreateOutcome(o) { return typeof o === \"object\" && o !== null && typeof o.ok === \"boolean\"; }\nfunction isWorkspaceResult(r) { return typeof r.workspaceId === \"string\" && r.workspaceId !== \"\"; }","tryCatchPattern":"try {\n  const ws = await createWorkspaceWithOutcome(options);\n  if (!isWorkspaceResult(ws)) throw new Error(\"create returned non-workspace\");\n} catch (e) {\n  // the dock keeps the failed row — check it for the specific cause, then retry or dismiss\n  editor.error(`workspace create rejected: ${e}`);\n}","preventionTips":["Treat a rejected create promise as a hard failure in scripts — do not swallow it.","Inspect the dock's retained failed row for the specific outcome.error when the thrown message is generic.","Fix runtime preconditions (host reachability, resources) before retrying a failed create.","Log editor.debug/error output around awaitCreateOutcome to capture causes the generic message omits."],"tags":["workspace","async","lifecycle","agent-orchestration"],"backgroundTag":"invalid-state-transition","analyzedSha":"67894ca5463dbd7a89bb31add4627c27d6b79d83","analyzedAt":"2026-09-13T15:04:03.701Z","contentChangedAt":"2026-09-13T15:04:03.701Z","schemaVersion":2},"datasetVersion":"2026-09-16T04:17:20.429Z"}