Skip to content

workflow: dispose() drops the ephemeral Bot records before the release finishes #1387

Closed

Description

@Birfy

Found by Reviewer while reviewing #1380 (ephemeral workflow Bots), each line re-read by me on main bcb039ef.

Where plugins/workflow/src/service.js:552-561

dispose() {
  const ids = Object.values(state.runs).flatMap(run => Object.values(run?.ephemeral ?? {}))
  for (const run of Object.values(state.runs)) {
    if (!run) continue
    delete run.ephemeral
    delete run.handed
  }
  if (ids.length > 0) write()
  void releaseAll(ids, release, warn)
},

What goes wrong — write() lands the state with ephemeral/handed already gone, and releaseAll is fired without being awaited (void). On a hot reload or process exit the release can be cut off half-way, so those Bots stay in the roster as hidden forever: the user cannot see them and cannot delete them. The longer the plugin lives the more of them accumulate.

Fix — release first, then delete and write(), and return the promise so the host can await dispose().

Same area, smaller — plugins/workflow/index.js:27,47,56-59: liveNames gains a name in spawn() but release(id) never removes it, so the set grows without bound inside one process.

Reproduce — start a workflow with spawn returning ids, call dispose() while release is slow (returns a pending promise), then read the persisted state: runs[*].ephemeral is gone while release never resolved.

Metadata

Metadata

Assignees

No one assigned

    Labels

    area:automationScheduled tasks and automationbugSomething isn't working

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions