Skip to content

Revert "fix(sockets): joining currently deleted workflow"#4036

Merged
icecrasher321 merged 1 commit intostagingfrom
revert-4004-fix/client-join-error
Apr 8, 2026
Merged

Revert "fix(sockets): joining currently deleted workflow"#4036
icecrasher321 merged 1 commit intostagingfrom
revert-4004-fix/client-join-error

Conversation

@icecrasher321
Copy link
Copy Markdown
Collaborator

Reverts #4004

@vercel
Copy link
Copy Markdown

vercel bot commented Apr 8, 2026

The latest updates on your projects. Learn more about Vercel for GitHub.

1 Skipped Deployment
Project Deployment Actions Updated (UTC)
docs Skipped Skipped Apr 8, 2026 3:37am

Request Review

@cursor
Copy link
Copy Markdown

cursor bot commented Apr 8, 2026

PR Summary

Medium Risk
Changes workflow room join/rejoin behavior on session errors and navigation, which can cause clients to attempt joining a workflow that was just deleted or referenced by a stale URL. Impact is limited to realtime collaboration UX but could reintroduce a previously fixed edge case.

Overview
Reverts the recent client-side safeguard that prevented the socket from rejoining/joining a workflow room immediately after receiving workflow-deleted.

This removes deletedWorkflowIdRef tracking and associated checks, so operation-forbidden (session expiration) and the URL-driven join effect will now attempt to join-workflow whenever a workflowId is present and the client isn’t already rejoining.

Reviewed by Cursor Bugbot for commit 95e02c2. Configure here.

@greptile-apps
Copy link
Copy Markdown
Contributor

greptile-apps bot commented Apr 8, 2026

Greptile Summary

This PR reverts #4004 ("fix(sockets): joining currently deleted workflow"), removing the guard that prevented the socket client from attempting to rejoin a workflow that was just deleted. No explanation is provided for why the fix is being reverted.

Key changes:

  • Removes deletedWorkflowIdRef ref that tracked the last deleted workflow's ID
  • Removes the assignment of deletedWorkflowIdRef.current in the workflow-deleted event handler
  • Removes the deletedWorkflowIdRef.current !== workflowId guard in the SESSION_ERROR / operation-forbidden path, which means a session-expiry rejoin will now target a deleted workflow if the URL still holds its ID
  • Removes the guard in the urlWorkflowId-change useEffect that skipped joining a workflow that had just been deleted but whose ID still appeared in the URL

The revert re-introduces the race condition that #4004 was specifically addressing: after a workflow-deleted event clears currentWorkflowId, there is a window where urlWorkflowId still references the deleted workflow (while router.push() propagates). During that window both the join-workflow useEffect and the SESSION_ERROR handler will attempt to emit join-workflow for a workflow that no longer exists on the server.

Confidence Score: 3/5

Not safe to merge without explanation — reintroduces a known race condition where the client attempts to join a deleted workflow room

The revert deliberately removes a targeted guard (deletedWorkflowIdRef) that prevented rejoining a deleted workflow during the URL-propagation window. This is a present defect on the changed path: any time a workflow is deleted, there is a real timing window during which both the useEffect and the SESSION_ERROR handler will emit join-workflow for a room that no longer exists. The PR description provides no context for why the fix is being reverted, making it impossible to evaluate whether an alternative approach is planned. Until the motivation is clear and a replacement guard is in place, this scores P1.

apps/sim/app/workspace/providers/socket-provider.tsx — the deleted-workflow guard was the only protection against the rejoin race condition

Vulnerabilities

No security concerns identified.

Important Files Changed

Filename Overview
apps/sim/app/workspace/providers/socket-provider.tsx Reverts the deleted-workflow guard, reintroducing a race condition where the client attempts to rejoin a workflow that was just deleted while the URL still holds its old ID

Sequence Diagram

sequenceDiagram
    participant Server
    participant Socket as SocketProvider
    participant Router as Next.js Router

    Server->>Socket: workflow-deleted { workflowId }
    Socket->>Socket: setCurrentWorkflowId(null)
    Note over Router: router.push() in progress — URL still = deleted workflowId

    alt SESSION_ERROR fires during propagation window
        Server->>Socket: operation-forbidden { type: SESSION_ERROR }
        Socket->>Socket: workflowId = urlWorkflowIdRef.current (= deleted ID)
        Socket->>Server: join-workflow { workflowId: deletedId } ❌
    end

    alt useEffect fires during propagation window
        Note over Socket: currentWorkflowId=null, urlWorkflowId=deletedId → not equal
        Socket->>Server: join-workflow { workflowId: deletedId } ❌
    end

    Router-->>Socket: URL updated to new workflowId
    Note over Socket: Race window closes
Loading

Comments Outside Diff (1)

  1. apps/sim/app/workspace/providers/socket-provider.tsx, line 503-510 (link)

    P1 Reintroduces deleted-workflow rejoin race condition

    Removing deletedWorkflowIdRef.current !== workflowId from the SESSION_ERROR guard means that if a SESSION_ERROR fires while urlWorkflowId still points to a deleted workflow (a timing window that exists until router.push() fully propagates the new URL), the socket will emit join-workflow for a workflow that no longer exists on the server.

    The same race condition is also reintroduced in the useEffect at line 554: when workflow-deleted sets currentWorkflowId to null but urlWorkflowId still holds the deleted ID, the condition currentWorkflowId === urlWorkflowId evaluates to false, causing join-workflow to be emitted for a deleted room.

    PR fix(sockets): joining currently deleted workflow #4004 was specifically introduced to close this gap. Is there a regression from that fix that motivates this revert? If so, it would help to document the reason so the root cause can be addressed without sacrificing the deleted-workflow guard.

Reviews (1): Last reviewed commit: "Revert "fix(sockets): joining currently ..." | Re-trigger Greptile

Copy link
Copy Markdown

@cursor cursor bot left a comment

Choose a reason for hiding this comment

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

Cursor Bugbot has reviewed your changes and found 1 potential issue.

Fix All in Cursor

❌ Bugbot Autofix is OFF. To automatically fix reported issues with cloud agents, enable autofix in the Cursor dashboard.

Reviewed by Cursor Bugbot for commit 95e02c2. Configure here.

// Prevent rejoining a workflow that was just deleted. The URL param may
// still reference the old workflow while router.push() propagates.
if (deletedWorkflowIdRef.current === urlWorkflowId) {
return
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Reverted guard allows rejoining a deleted workflow

Medium Severity

Removing deletedWorkflowIdRef reintroduces a race condition. When a workflow-deleted event fires, currentWorkflowId is set to null, but urlWorkflowId still references the deleted workflow (URL hasn't changed). The useEffect sees currentWorkflowId !== urlWorkflowId and immediately emits join-workflow for the deleted workflow. This also affects the operation-forbidden handler, which will attempt to rejoin a deleted workflow on SESSION_ERROR. Since onWorkflowDeleted has no consumers to trigger navigation, this race will reliably trigger for any user viewing a workflow deleted by someone else.

Additional Locations (1)
Fix in Cursor Fix in Web

Reviewed by Cursor Bugbot for commit 95e02c2. Configure here.

@icecrasher321 icecrasher321 merged commit 2760b4b into staging Apr 8, 2026
12 checks passed
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