Skip to content

fix(react): retry transient polling errors during app handoff - #310

Open
realmehmetali wants to merge 2 commits into
worldcoin:mainfrom
realmehmetali:agent/retry-transient-poll-errors
Open

fix(react): retry transient polling errors during app handoff#310
realmehmetali wants to merge 2 commits into
worldcoin:mainfrom
realmehmetali:agent/retry-transient-poll-errors

Conversation

@realmehmetali

@realmehmetali realmehmetali commented Jul 18, 2026

Copy link
Copy Markdown

Summary

  • retry transient polling rejections without recreating the active verification request
  • keep retries bounded while the page is visible and preserve the retry budget while it is backgrounded
  • apply the same behavior to request and invite-code React hooks
  • add regression coverage for recovery, visible retry limits, background handoff, and invite-code parity

Why

A single transient bridge or network rejection currently moves the React hook directly into its failed state. During a browser-to-World App handoff, that can discard an otherwise valid verification request and force the user to restart.

This was observed while exercising cross-app World ID verification for a project. The change is generic and contains no application-specific behavior.

Impact

There is no public API change. Terminal failed statuses continue to fail immediately. Only rejected poll attempts that map to connection_failed, generic_error, or unexpected_response are retried. The existing overall polling timeout remains authoritative.

Validation

  • pnpm --filter @worldcoin/idkit test — 38 tests passed
  • pnpm --filter @worldcoin/idkit type-check
  • pnpm --filter @worldcoin/idkit build
  • Prettier check on all changed files

Note

Medium Risk
Changes in-flight verification polling and error handling for all request and invite-code React flows, though behavior is bounded and non-retryable failures stay immediate.

Overview
React verification hooks no longer fail the whole flow on a single transient pollOnce rejection during browser-to-World App handoff. Polling now goes through pollOnceWithRetry, which retries transport-level errors (connection_failed, generic_error, unexpected_response) on the same request instead of recreating it.

Retries use exponential backoff (capped at 5s) and are limited to five consecutive failures while the tab is visible; when document.visibilityState is hidden, visible-retry counting pauses so the budget is not burned during the handoff. The flow’s existing overall polling timeout still wins, including rejecting a success that arrives after the deadline.

The same wrapper is wired into useIDKitFlow and useIDKitInviteCodeFlow. Terminal failed poll statuses and non-retryable errors are unchanged. Regression tests cover recovery, timeout enforcement, visible retry caps, hidden-tab behavior, and invite-code parity.

Reviewed by Cursor Bugbot for commit 36d26df. Bugbot is set up for automated code reviews on this repo. Configure here.

@vercel

vercel Bot commented Jul 18, 2026

Copy link
Copy Markdown

@realmehmetali is attempting to deploy a commit to the Tools For Humanity Team on Vercel.

A member of the Team first needs to authorize it.

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: af05995693

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread js/packages/react/src/hooks/common.ts Outdated
}

try {
return await pollOnce();

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Recheck the timeout after each retry poll

When a retry begins shortly before the configured deadline and pollOnce() resolves after it, this immediate return accepts a late confirmation—or another nonterminal status—without checking elapsed time again. This makes the overall polling timeout non-authoritative specifically for the newly added retry attempts; validate the deadline after the awaited poll before returning its result.

Useful? React with 👍 / 👎.

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Addressed in 36d26df. pollOnceWithRetry now rechecks the overall deadline after each awaited poll and rejects a result that resolves late. The regression advances time past the boundary during the retry result and asserts Timeout. Validation: all 39 React-package tests, typecheck, package build, Prettier, and the required core/server dependency builds pass.

@realmehmetali
realmehmetali force-pushed the agent/retry-transient-poll-errors branch from af05995 to 36d26df Compare July 28, 2026 01:40
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant