[core] Fix stable e2e: hookGetConflict test references undefined waitForHook#2405
Merged
Conversation
The `hookGetConflictWorkflow ... resolves with the conflicting run` e2e test was backported (#2372/#2382) calling `waitForHook(token, {runId})`, a helper that only exists on `main`. On `stable` the equivalent helper is `waitForHookState(token, predicate)`, so the call threw `ReferenceError: waitForHook is not defined`, failing the whole e2e suite on every stable push and stable-targeted PR. hook.getConflict() itself works on stable (sibling tests pass) — this is purely a missing test helper. Switch the call to the predicate form already used by 8 other sites in this file. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Contributor
🦋 Changeset detectedLatest commit: de647b6 The changes in this PR will be included in the next version bump. This PR includes changesets to release 0 packagesWhen changesets are added to this PR, you'll see the packages that this PR includes changesets for and the associated semver types Not sure what this means? Click here to learn what changesets are. Click here if you're a maintainer who wants to add another changeset to this PR |
Contributor
🧪 E2E Test Results❌ Some tests failed Summary
❌ Failed Tests🌍 Community Worlds (102 failed)mongodb (17 failed):
redis (12 failed):
turso (73 failed):
Details by Category✅ ▲ Vercel Production
✅ 💻 Local Development
✅ 📦 Local Production
✅ 🐘 Local Postgres
✅ 🪟 Windows
❌ 🌍 Community Worlds
✅ 📋 Other
|
pranaygp
approved these changes
Jun 13, 2026
pranaygp
added a commit
that referenced
this pull request
Jun 13, 2026
…getRun API The backport of #2387 used APIs that only exist on `main`, breaking the nextjs-turbopack/webpack builds and the e2e suite on `stable`: - `hookAdoptOwnerResultWorkflow`/`hookSupersedeOwnerWorkflow` read `conflict.returnValue`/`conflict.cancel()`, but on `stable` `getConflict()` resolves with `{ runId }`. Resolve the owning run via `getRun(conflict.runId)` inside a step (the documented stable pattern) to await its result / cancel it. - Import `resumeHook` from `workflow/api` in 99_e2e.ts (was used by `forwardPayloadToOwner` but never imported). - Convert the backported `waitForHook(token, { runId })` call sites to `waitForHookState(token, predicate)`; `waitForHook` does not exist on `stable` (#2405 standardized on `waitForHookState`). Both workbench builds and `biome check` pass locally. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
pranaygp
added a commit
that referenced
this pull request
Jun 14, 2026
…ing strategies (#2402) * test: e2e coverage for run-idempotency conflict-handling strategies (#2387) * test: e2e coverage for run-idempotency conflict-handling strategies Covers the patterns documented in foundations/idempotency: - claim-only hook mutex: token claimed and held with no payload data, duplicate identifies the owner, token released after completion - adopt the owner's result via conflict.returnValue - signal the owner: duplicate forwards its payload via resumeHook - supersede: duplicate cancels the owner and reclaims the token - route-side resume-or-start retry pattern reaching the started run Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> * test: fix adopt-owner-result race — gate owner completion on observed conflict On slow runtimes the duplicate's first invocation could land after the owner completed and released the token, making the duplicate a fresh owner that waits forever for a payload (90s timeout across CI matrices). Poll the duplicate's event log for hook_conflict before resuming the owner, and widen the test timeout for the added gate budget. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> * review: assert superseded owner's returnValue rejection; empty changeset - Await run1.returnValue and assert WorkflowRunCancelledError so the cancellation is verified end-to-end and no rejection leaks from the supersede test. - Test-only PR: use an empty changeset. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> * ci: retrigger preview deployments (turbopack deployment for 2e9d000 wedged in esbuild hang) Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> * ci: bust poisoned turbo cache entry for nextjs-turbopack build The 2e9d000 deployment's next build crashed in an esbuild hang but its task (70724907c9dd3a29) was recorded into the turbo remote cache anyway, so every subsequent build with the same input hash replays the broken artifact (missing routes-manifest). Change a build input to force a fresh execution. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> --------- Co-authored-by: Claude Fable 5 <noreply@anthropic.com> Signed-off-by: Pranay Prakash <pranay.gp@gmail.com> * fix(backport): adapt conflict-handling tests to stable's getConflict/getRun API The backport of #2387 used APIs that only exist on `main`, breaking the nextjs-turbopack/webpack builds and the e2e suite on `stable`: - `hookAdoptOwnerResultWorkflow`/`hookSupersedeOwnerWorkflow` read `conflict.returnValue`/`conflict.cancel()`, but on `stable` `getConflict()` resolves with `{ runId }`. Resolve the owning run via `getRun(conflict.runId)` inside a step (the documented stable pattern) to await its result / cancel it. - Import `resumeHook` from `workflow/api` in 99_e2e.ts (was used by `forwardPayloadToOwner` but never imported). - Convert the backported `waitForHook(token, { runId })` call sites to `waitForHookState(token, predicate)`; `waitForHook` does not exist on `stable` (#2405 standardized on `waitForHookState`). Both workbench builds and `biome check` pass locally. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> * fix(backport): import HookNotFoundError in e2e test The backported conflict tests call `HookNotFoundError.is()` in `hookClaimOnlyMutexWorkflow` (token-release wait) and the resume-or-start route test, but the import was never carried into the stable test file — causing a runtime `ReferenceError: HookNotFoundError is not defined`. Import it from `@workflow/errors` (matches `main`). Verified locally against nextjs-turbopack: the two previously-failing tests plus the adopt/signal/supersede rewrites all pass (5/5). Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> --------- Signed-off-by: Pranay Prakash <pranay.gp@gmail.com> Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com> Co-authored-by: Claude Fable 5 <noreply@anthropic.com> Co-authored-by: Pranay Prakash <pranay.gp@gmail.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Problem
stable's e2e suite has been red on every push since 2026-06-12 (and on every stable-targeted PR, e.g. the backports #2401/#2402/#2404), failing with:Root cause
The
hookGetConflicttest was brought ontostableby backports #2372 ("Addhook.hasConflict") and #2382 ("Replace hook.hasConflict with hook.getConflict()"). It callswaitForHook(token, { runId })— a helper that only exists onmain. Onstablethe hook-polling helper iswaitForHookState(token, predicate)(different signature), so the call references an undefined function and the wholee2e.test.tsfile aborts.This is not an implementation problem:
hook.getConflict()works onstable— the siblinggetConflicttests in the same file pass. It's purely a missing/renamed test helper that wasn't carried with the backport (thewaitForHookhelper was added onmainby a separate, never-backported PR).Fix
Switch the single offending call to the predicate form already used by 8 other call sites in this file (and an identical pattern at line ~1442):
Semantics are identical to
main'swaitForHook(token, {runId}): resolve once a hook for the token exists whoserunIdmatchesrun1.This greens
stable's own push CI and unblocks the in-flight backport PRs on re-run.Test-only change → empty changeset.
🤖 Generated with Claude Code