Skip to content

fix(ENG-12551): fix COOP detection race condition and empty response parsing#135

Merged
adefreitas merged 1 commit into
StackOneHQ:mainfrom
adefreitas:fix/coop-popup-close-race-condition
Apr 16, 2026
Merged

fix(ENG-12551): fix COOP detection race condition and empty response parsing#135
adefreitas merged 1 commit into
StackOneHQ:mainfrom
adefreitas:fix/coop-popup-close-race-condition

Conversation

@adefreitas

@adefreitas adefreitas commented Apr 16, 2026

Copy link
Copy Markdown
Collaborator

Summary

  • Fix COOP race condition: COOP detection at popup open time is unreliable — the browser starts the popup at about:blank before enforcing the policy, so connectWindow.closed reads false initially. When COOP kicks in later, the popup watcher incorrectly interprets it as user-closed and cancels the connection attempt, resetting back to edit mode. Fixed by deferring to polling whenever it is active, regardless of COOP detection.
  • Fix empty response crash: DELETE /connection_attempts/:id returns an empty body, causing response.json() to throw. Now reads as text first and only parses if non-empty.
  • Reduce cancel button delay: from 8s to 5s for faster user recovery.

Test plan

  • Open OAuth popup with a provider that sets COOP headers — verify the hub stays in loading state and polling resolves the connection
  • Close the popup manually during OAuth — verify the cancel button appears after 5s and works correctly
  • Cancel a connection attempt — verify no console error from the DELETE response parsing
  • Complete a successful OAuth flow — verify it still works end-to-end

🤖 Generated with Claude Code


Summary by cubic

Fixes OAuth popup COOP race by always using polling when active, preventing early cancellation. Also handles empty HTTP responses and shows the cancel button sooner. Supports ENG-12551 by keeping the hub in loading while server-side polling completes under COOP.

  • Bug Fixes
    • Always defer to polling when active, ignoring early COOP detection to avoid misinterpreting popup closure during about:blank → COOP transition.
    • In request<T>(), read response.text() and JSON-parse only if non-empty to avoid crashes on empty DELETE responses.
    • Reduce cancel button delay from 8s to 5s for faster recovery.

Written for commit 24c2f7c. Summary will update on new commits.

…parsing

COOP detection at popup open time is unreliable because the browser
hasn't enforced the policy yet (popup starts at about:blank). When COOP
kicks in later, the popup watcher incorrectly treats it as user-closed
and cancels the connection attempt. Fix by deferring to polling whenever
it is active, regardless of COOP detection.

Also fix DELETE response parsing crash (empty body) and reduce cancel
button delay from 8s to 5s.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Copilot AI review requested due to automatic review settings April 16, 2026 15:02

@claude claude 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.

Claude Code Review

This pull request is from a fork — automated review is disabled. A repository maintainer can comment @claude review to run a one-time review.

@cubic-dev-ai cubic-dev-ai 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.

No issues found across 3 files

Requires human review: Modifies core httpClient logic and OAuth flow handling, which have high blast radii and require human verification of side effects.

@adefreitas adefreitas merged commit 7520687 into StackOneHQ:main Apr 16, 2026
8 checks passed

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Pull request overview

This PR improves the OAuth “connect account” flow reliability by preventing false “popup closed” handling when COOP is enforced, hardens the shared HTTP client against empty DELETE responses, and shortens the time before users can cancel a stalled connection attempt.

Changes:

  • Adjust OAuth popup watcher logic to defer “popup closed” handling when polling is active (COOP race mitigation).
  • Update httpClient response parsing to tolerate empty response bodies by parsing text conditionally.
  • Reduce the cancel affordance delay in the loading UI from 8s to 5s.

Reviewed changes

Copilot reviewed 3 out of 3 changed files in this pull request and generated 3 comments.

File Description
src/shared/httpClient.ts Changes response parsing to avoid response.json() throwing on empty bodies.
src/shared/components/loading.tsx Speeds up showing the “Cancel and start over” action.
src/modules/integration-picker/hooks/useIntegrationPicker.ts Prevents popup watcher from cancelling/resetting while polling is active (COOP mitigation).

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread src/shared/httpClient.ts

return (await response.json()) as T;
const text = await response.text();
if (!text) return null;
window.removeEventListener('message', processMessageCallback, false);

if (coopDetectedRef.current && pollingIntervalRef.current) return;
if (pollingIntervalRef.current) return;
Comment thread src/shared/httpClient.ts
Comment on lines +57 to 60
const text = await response.text();
if (!text) return null;
return JSON.parse(text) as T;
}
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.

2 participants