{"record":{"id":"ede21ec5d675c8bf","repo":"BloopAI/vibe-kanban","slug":"cannot-run-script-while-another-process-is-running","errorCode":null,"errorMessage":"Cannot run script while another process is running","messagePattern":"Cannot run script while another process is running","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"warning","filePath":"packages/web-core/src/shared/actions/index.ts","lineNumber":1170,"sourceCode":"  },\n\n  // === Script Actions ===\n  RunSetupScript: {\n    id: 'run-setup-script',\n    label: 'Run Setup Script',\n    icon: TerminalIcon,\n    shortcut: 'R S',\n    requiresTarget: ActionTargetType.WORKSPACE,\n    isVisible: (ctx) => ctx.hasWorkspace,\n    isEnabled: (ctx) => !ctx.isAttemptRunning,\n    execute: async (_ctx, workspaceId) => {\n      const result = await workspacesApi.runSetupScript(workspaceId);\n      if (!result.success) {\n        if (result.error?.type === 'no_script_configured') {\n          throw new Error('No setup script configured for this project');\n        }\n        if (result.error?.type === 'process_already_running') {\n          throw new Error('Cannot run script while another process is running');\n        }\n        throw new Error('Failed to run setup script');\n      }\n    },\n  },\n\n  RunCleanupScript: {\n    id: 'run-cleanup-script',\n    label: 'Run Cleanup Script',\n    icon: TerminalIcon,\n    shortcut: 'R C',\n    requiresTarget: ActionTargetType.WORKSPACE,\n    isVisible: (ctx) => ctx.hasWorkspace,\n    isEnabled: (ctx) => !ctx.isAttemptRunning,\n    execute: async (_ctx, workspaceId) => {\n      const result = await workspacesApi.runCleanupScript(workspaceId);\n      if (!result.success) {\n        if (result.error?.type === 'no_script_configured') {","sourceCodeStart":1152,"sourceCodeEnd":1188,"githubUrl":"https://github.com/BloopAI/vibe-kanban/blob/4deb7eca8f381f7cbc1f9d15515a9ab8f8009053/packages/web-core/src/shared/actions/index.ts#L1152-L1188","documentation":"Thrown by the RunSetupScript action when the backend reports error.type === 'process_already_running', meaning another execution process (a previous script run or a running attempt) is currently active on the workspace and the executor refuses to start a second one concurrently.","triggerScenarios":"Calling workspacesApi.runSetupScript while a prior setup/cleanup/archive script or attempt process is still executing on the same workspace; the server rejects with process_already_running.","commonSituations":"Double-clicking the run action so two invocations race, a previous script hanging (long install, waiting on input) and never finishing, or a crashed run that left the process state marked running on the server.","solutions":["Wait for the current process to finish (the action already disables the button via !ctx.isAttemptRunning — ensure ctx is fresh).","Stop/cancel the running attempt or script from the UI, then re-run the setup script.","If the prior run crashed and the server state is stale, restart the backend or kill the orphaned process to clear the running state.","Serialize user-triggered runs: keep the button disabled while a run is in flight instead of re-checking only on render."],"exampleFix":"// before\nisEnabled: (ctx) => !ctx.isAttemptRunning,\n// after\nlet running = false;\nexecute: async (ctx, workspaceId) => {\n  if (running) return;\n  running = true;\n  try { await workspacesApi.runSetupScript(workspaceId); }\n  finally { running = false; }\n}","handlingStrategy":"retry","validationCode":"// before running\nif (isAttemptRunning || scriptInFlight) {\n  toast.info('Another process is running; wait for it to finish.');\n  return;\n}\nawait workspacesApi.runSetupScript(workspaceId);","typeGuard":"function isBusyError(result: RunScriptResult): boolean {\n  return result.success === false && result.error?.type === 'process_already_running';\n}","tryCatchPattern":"try {\n  const result = await workspacesApi.runSetupScript(workspaceId);\n  if (!result.success && result.error?.type === 'process_already_running') {\n    await waitForAttemptToFinish(workspaceId);\n    return retrySetupScript(workspaceId); // single retry after busy state clears\n  }\n} catch (err) {\n  toast.error(String(err));\n}","preventionTips":["Keep the run button disabled while isAttemptRunning is true (with fresh context).","Debounce/deduplicate rapid clicks with an in-flight flag.","Stop hung attempts from the UI before re-running scripts.","Monitor for orphaned processes after backend crashes and restart to clear stale busy state."],"tags":["concurrency","process","workspace"],"backgroundTag":"process-already-running","analyzedSha":"4deb7eca8f381f7cbc1f9d15515a9ab8f8009053","analyzedAt":"2026-08-29T09:24:13.446Z","schemaVersion":2},"datasetVersion":"2026-08-29T12:17:43.993Z"}