You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Browse filesBrowse the repository at this point in the historyBrowse files
authored
fix(first-run-tour): fail a run the queue never accepted (#15091)
Closes#14619 — the one finding from release verification I said I'd
hold the
release for. It has been sitting fixed-but-unopened on a branch; this
brings it
onto current `main`.
## What breaks today
A **paid** subscriber who is out of credits reaches the tour's Run step,
clicks
Run, and the tour advances to the Result step. The backend refuses the
submission. The card then shows *"Hang tight — your result lands right
here the
moment it's ready"* **forever**: no error, no terminal state, no way
forward
except closing the tour.
## Why every existing guard misses it
- A refused submission never gets a `prompt_id`, so **no workflow status
ever
appears** and none of the `running` / `completed` / `failed` branches
can fire.
- Account preconditions — sign-in, subscription, credits — are
deliberately kept
out of the error stores by `ComfyApp.queuePrompt`, so the `refused` term
cannot see them either.
- `canRunWorkflows` is `isActiveSubscription && (!isFreeTier || …)`,
which is
**true** for this user, so the paywall branch never postpones the tour.
Three independent mechanisms, all structurally blind to the same case.
## The fix
A deadline on **acceptance**, not on the run:
```ts
const ACCEPT_DEADLINE_MS = 15_000
```
Started when the click reports `generating`, and cleared by *any* status
at all
(`if (status !== undefined) stopAcceptDeadline()`). So a job that is
merely slow
is never cut short — only a submission the queue never acknowledged
fails.
## Verification
`pnpm vitest run src/renderer/extensions/firstRunTour/` — **189 passed
(10
files)**. `typecheck` and `format:check` clean.
Mutation-tested rather than asserted-green:
| mutation | result |
| --- | --- |
| drop `startAcceptDeadline()` | **1 failed** / 51 passed |
| drop the `status !== undefined` clear | **4 failed** / 48 passed |
| unmutated | 52 passed |
The second one matters: without it the deadline would fail *accepted*
runs too,
and four tests — including the offline-grace ones — catch that.
Also fixes the `generatingRun` test helper, which never acknowledged its
run and
so was silently modelling a refusal; it now reports a status, matching
what the
queue actually does, and the unacknowledged case gets its own test.
## Scope
This is the **engineering half** of #14619. Deep ruled that this
population
should be *skipped* — not shown a tour they cannot complete. That
product
decision is not implemented here and #14619's product half stays with
@MaanilVerma. What this changes is that the failure is now terminal and
legible
instead of an indefinite promise.
---------
Co-authored-by: Claude Opus 5 (1M context) <noreply@anthropic.com>
Co-authored-by: t <t@t.t>
Co-authored-by: Alexander Brown <drjkl@comfy.org>
Co-authored-by: Connor Byrne <c.byrne@comfy.org>
0 commit comments