{"record":{"id":"75a65d60c9d15414","repo":"sinelaw/fresh","slug":"workspace-is-still-being-created-and-cannot-be-verb","errorCode":null,"errorMessage":"workspace is still being created and cannot be ${verb}","messagePattern":"workspace is still being created and cannot be (.+?)","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"crates/fresh-editor/plugins/orchestrator.ts","lineNumber":10576,"sourceCode":"    if (stable === target) return session;\n  }\n  return null;\n}\n\n/// A workspace still being created has no durable identity and no worktree\n/// yet — the dock offers it Retry / Dismiss and nothing else, so the verbs\n/// that organise a *real* workspace refuse it here rather than writing a name\n/// or a folder assignment against a placeholder key that is about to vanish.\n// Guard the verbs that need somewhere durable to record their result.\n//\n// A workspace still being created keys its name and its folder off the\n// durable `stableId` it was born with, so both survive the build and both\n// are safe to set while it runs. A *windowless* placeholder (a remote\n// create, whose window is born by the connect) has no such id yet — there\n// is nothing to file the change against, so it is still refused.\nfunction rejectPending(s: AgentSession, verb: string): void {\n  if (s.pending && !s.stableId) {\n    throw new Error(`workspace is still being created and cannot be ${verb}`);\n  }\n}\n\n/// Push folder-tree changes into an open dock. The tree's expansion set is\n/// host-owned state seeded from the plugin's persisted set, so a folder\n/// created or deleted behind the dock's back has to be re-seeded before the\n/// re-render — the same two steps `submitCreateFolder` runs.\nfunction refreshDockTree(): void {\n  if (openPanel && dockMode) {\n    openPanel.setExpandedKeys(\"sessions\", Array.from(loadExpanded()));\n  }\n  refreshOpenDialog();\n}\n\nfunction apiRenameWorkspace(target: string | number, name?: string): boolean {\n  const s = resolveWorkspace(target);\n  if (!s) return false;\n  rejectPending(s, \"renamed\");","sourceCodeStart":10558,"sourceCodeEnd":10594,"githubUrl":"https://github.com/sinelaw/fresh/blob/67894ca5463dbd7a89bb31add4627c27d6b79d83/crates/fresh-editor/plugins/orchestrator.ts#L10558-L10594","documentation":"This error is thrown by rejectPending() when an operation is attempted against an agent session that is still being created: it has a pending placeholder state but no durable stableId yet. A stableId is assigned once the session's window/build settles, so any verb (rename, file-into-folder, etc.) called before that would have nothing durable to operate on. The library refuses the call instead of silently applying it to a session that may be replaced by the pending build.","triggerScenarios":"Calling an orchestrator API (e.g. rename or assign-session-to-folder) against a workspace whose session record is a pending placeholder without a stableId — typically a remote create whose window is born by the connect step, or any call racing the workspace creation build.","commonSituations":"Automated scripts that create a workspace and immediately rename or file it without waiting for creation to complete; event handlers reacting to a session-appearing event fired before the build finishes; tests that don't await workspace readiness.","solutions":["Wait for workspace creation to complete (await the create call or poll until the session has a stableId) before invoking further verbs","Retry the operation after the creation/build event fires; the same call succeeds once stableId is assigned","If it's a local create, ensure the stableId path is used — local placeholders carry their durable id from birth, so only remote/abnormal flows should hit this"],"exampleFix":"// before\napi.assignSessionToFolder(newWs.id, folderId);\n// after\nawait orchestrator.waitForWorkspaceReady(newWs.id);\napi.assignSessionToFolder(newWs.id, folderId);","handlingStrategy":"retry","validationCode":"const ready = (ws) => ws && ws.stableId != null && !ws.pending;\nif (!ready(api.getWorkspace(id))) await waitForReady(id);","typeGuard":"function isSessionReady(s) {\n  return s != null && !s.pending && typeof s.stableId === \"string\" && s.stableId.length > 0;\n}","tryCatchPattern":"try {\n  api.renameWorkspace(id, name);\n} catch (e) {\n  if (String(e).includes(\"still being created\")) {\n    await waitForWorkspaceReady(id);\n    api.renameWorkspace(id, name);\n  } else throw e;\n}","preventionTips":["Always await the workspace create call before issuing follow-up verbs","Gate follow-up operations on the presence of stableId","Subscribe to the creation-complete/build event instead of polling blindly","In tests, use the harness's readiness helper rather than fixed timeouts"],"tags":["typescript","race-condition","workspace-lifecycle"],"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"}