Skip to content

fix(workflow): keep a run Bot's id when its release fails #1616

Closed

Description

@HugoXK

Implementation: FlyBot (ours) — PR follows within 24h. Do not pick up without a pickup-ok comment on this issue.

Written-by: FlyBot Lead
Claimed-by: FlyBot Lead
Claim-Id: 035cbfa28abf435ca3c6b49c52c08da8
Branch: dev3/fix/p116-ephemeral-release-id
Base: bde09d1
At: 2026-10-29T01:06:24Z

What happens

A run Bot that cannot be released is forgotten anyway, so it becomes a permanent hidden orphan.

releaseAll() (plugins/workflow/src/ephemeral.js:66-81) returns the ids whose release failed and documents the contract: "that Bot is still there, so the caller must keep naming it and let a later attempt retry the release (#1476)". Three call sites drop that return value and delete the id first:

path line (bde09d1) what it does
releaseRun() service.js:598 delete, :608 await releaseAll(ids, release, warn) deletes run.ephemeral before releasing, ignores failed. This is the normal end of every run (:235 timeout, :808 dispatch failure, :812 end), not just shutdown.
dispose() service.js:1559-1564 releaseAll(ids, release, warn).then(() => { for (const run of runs) { delete run.ephemeral … } }) the .then() runs on every outcome and strips ephemeral from every run, including the ones that failed to release
reap() service.js:1504, :1516 delete; :1529 releaseAll(stale, …) same shape at load; deletes the ids before releasing

reset() (service.js:1324-1326) already does it right: it takes failed from releaseAll, saved.hold(failed) keeps the ids, freezes them and says "N Bots were not released". dispose()'s own comment at :1552-1557 and test/dispose.test.js:1-3 describe exactly the bug being committed: "A record that drops an id before its Bot is gone leaves a hidden Bot that no state names, so nothing can ever find it again."

Reproduction (live main bde09d1)

Copy plugins/workflow/test/dispose.test.js, add one case with two nodes whose release throws host call failed for eph-code-*, run node --import ./test/resolve.mjs --test test/zz-probe-dispose.test.js. Observed:

ids ["eph-plan-1","eph-code-2"]
afterDispose ephemeral null
warnings ["flybot-workflow: could not remove eph-code-2: host call failed"]
releasedOnDispose ["eph-plan-1"]
releasedOnReload []          # same dir: createWorkflowService() again + reap()

reap() on reload is the only recovery path, and the record already dropped the id, so it never retries. Probe file deleted; nothing left in the repo.

Consequence: eph-code-2 stays a hidden run Bot — core-host.md:337 (not in sidebar/Search/Settings→Bots, skipped by list_bots) and plugin-runtime.md:68 (bot.list omits it). No UI can see or delete it, it keeps its name (findBot still resolves it) so a later Bot cannot reuse it, and its Session is never reclaimed.

Expected

Only ids that really went away are forgotten:

  • dispose(): keep run.ephemeral for runs whose ids came back in failed; drop it only for the released ones. A later load's reap() then retries the rest.
  • releaseRun(): same — failed ids stay in the record (and are warned once) instead of being deleted up front.
  • reap(): delete an id only after releaseAll reports it as released.

Scope (S)

service.js three call sites, 2-4 lines each, plus one regression test in plugins/workflow/test/dispose.test.js: release throws for one id → that id is still in the run record after dispose(), exactly one could not remove … warning, and a reloaded service reap() retries it (does not come back []).

Not in scope: reset() (already correct), migrateRuns() legacy rows, release retry policy/backoff, any UI.

Dedup

No open issue covers release/dispose leaks: #1472, #1476 are closed; searched dispose, ephemeral, releaseAll, orphan — none of the open ones describe this path.

Activity

  1. HugoXK commented on Oct 29, 2026

    @HugoXK
    ContributorAuthor

    Release

    Written-by: FlyBot Lead
    Released: 035cbfa28abf435ca3c6b49c52c08da8
    Reason: merged as 3dc44ec via #1617
    At: 2026-10-29T01:43:19Z

  2. HugoXK commented on Oct 29, 2026

    @HugoXK
    ContributorAuthor

    Release

    Written-by: FlyBot Lead
    Released: 035cbfa28abf435ca3c6b49c52c08da8
    Reason: merged as 3dc44ec (PR #1617, merged_by Birfy at 2026-10-29T01:37:29Z)
    At: 2026-10-29T01:51:51Z

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions