Skip to content

feat(canvas): allow locked block outbound connections#3229

Merged
waleedlatif1 merged 2 commits intostagingfrom
cursor/locked-block-outbound-connections-6872
Feb 18, 2026
Merged

feat(canvas): allow locked block outbound connections#3229
waleedlatif1 merged 2 commits intostagingfrom
cursor/locked-block-outbound-connections-6872

Conversation

@emir-karabeg
Copy link
Collaborator

Summary

This PR modifies the block protection logic to allow adding and removing outbound connections from locked blocks. Previously, all connections involving a locked block (both inbound and outbound) were protected. Now, only inbound connections to a locked block are protected, ensuring that a locked block's internal state cannot be altered by external connections, while still allowing its outputs to be freely managed.

Fixes # (issue) - Assuming this is an improvement, not a specific bug fix, but linking to an issue if one exists would be good.

Type of Change

  • Bug fix
  • New feature
  • Breaking change
  • Documentation
  • Other: ___________

Testing

The isEdgeProtected function was updated to only consider the target block for protection. This allows operations on outbound connections from locked blocks while maintaining protection for inbound connections.
Reviewers should verify:

  • It is now possible to add new outbound connections from a locked block.
  • It is now possible to remove existing outbound connections from a locked block.
  • It is still not possible to add new inbound connections to a locked block.
  • It is still not possible to remove existing inbound connections to a locked block.
  • Error messages and comments related to block protection have been updated to reflect this change (e.g., "Cannot remove connections to locked blocks" instead of "from locked blocks").
  • tsc and lint checks passed.

Checklist

  • Code follows project style guidelines
  • Self-reviewed my changes
  • Tests added/updated and passing
  • No new warnings introduced
  • I confirm that I have read and agree to the terms outlined in the Contributor License Agreement (CLA)

Screenshots/Videos


Slack Thread

Open in Cursor Open in Web

- Modified isEdgeProtected to only check target block protection
- Outbound connections (from locked blocks) can now be added/removed
- Inbound connections (to locked blocks) remain protected
- Updated notification messages and comments to reflect the change

Co-authored-by: Emir Karabeg <[email protected]>
@cursor
Copy link

cursor bot commented Feb 16, 2026

Cursor Agent can help with this pull request. Just @cursor in comments and I'll start working on changes in this branch.
Learn more about Cursor Agents

@vercel
Copy link

vercel bot commented Feb 16, 2026

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

1 Skipped Deployment
Project Deployment Actions Updated (UTC)
docs Skipped Skipped Feb 18, 2026 2:15am

Request Review

@waleedlatif1 waleedlatif1 marked this pull request as ready for review February 17, 2026 18:09
@waleedlatif1 waleedlatif1 changed the title Locked block outbound connections feat(canvas): allow locked block outbound connections Feb 17, 2026
@waleedlatif1
Copy link
Collaborator

@cursor review

@waleedlatif1
Copy link
Collaborator

@greptile

@greptile-apps
Copy link
Contributor

greptile-apps bot commented Feb 17, 2026

Greptile Summary

This PR modifies the block protection logic so that only inbound connections to a locked block are protected — outbound connections from a locked block can now be freely added or removed. The change is implemented in two files:

  • block-protection-utils.ts: isEdgeProtected now only calls isBlockProtected on the target of an edge, removing the previous || isBlockProtected(edge.source, blocks) check.
  • workflow.tsx: All four call sites of isEdgeProtected now have updated comments and notification messages to reflect the new semantics.

The change is logically consistent, minimal, and all four usage points (onEdgesChange, onConnect, handleEdgeDelete, keyboard Delete handler) are updated in sync.

One minor issue found:

  • The onConnect notification message was shortened from 'Cannot connect to locked blocks or blocks inside locked containers' to 'Cannot connect to locked blocks'. Since isBlockProtected still protects nodes inside locked containers (via the parent check at block-protection-utils.ts:32), this message is technically inaccurate — users trying to connect to a block inside a locked container will get an unhelpful message suggesting only the target block itself would be the issue.

Confidence Score: 4/5

  • Safe to merge with one minor notification message inaccuracy.
  • The core logic change is correct and minimal — removing the source-side lock check from isEdgeProtected is the right approach to allow outbound connections from locked blocks. All four call sites are updated consistently. The only issue is the shortened notification message in onConnect that no longer mentions "blocks inside locked containers," even though that case is still blocked. This is a UX/clarity issue, not a functional regression.
  • workflow.tsx line 2602 — notification message should be restored to mention locked containers.

Important Files Changed

Filename Overview
apps/sim/app/workspace/[workspaceId]/w/[workflowId]/utils/block-protection-utils.ts Core utility change: isEdgeProtected now only checks the target block (not source), enabling outbound connections from locked blocks. Logic is minimal, correct, and well-documented.
apps/sim/app/workspace/[workspaceId]/w/[workflowId]/workflow.tsx All four call sites of isEdgeProtected are updated consistently. Comments and notification messages are updated to reflect the new semantics. Minor: the notification in onConnect dropped the "or blocks inside locked containers" clause even though isBlockProtected still protects those nodes, making the error message slightly inaccurate for that scenario.

Flowchart

flowchart TD
    A[User attempts edge operation] --> B{Operation type?}
    B --> |Add connection| C[onConnect called]
    B --> |Remove via ReactFlow| D[onEdgesChange called]
    B --> |Remove via delete button| E[handleEdgeDelete called]
    B --> |Remove via keyboard| F[handleKeyDown Delete/Backspace]

    C --> G[isEdgeProtected check]
    D --> H[isEdgeProtected filter]
    E --> I[isEdgeProtected check]
    F --> J[isEdgeProtected filter]

    G --> K{isBlockProtected target?}
    H --> K
    I --> K
    J --> K

    K --> |target is locked or in locked container| L[Block operation\nShow notification]
    K --> |target is unlocked| M{Source check?}

    M --> |OLD: also check source| N[Block if source locked]
    M --> |NEW: skip source check| O[Allow operation\nEven if source is locked]

    style N fill:#ffcccc
    style O fill:#ccffcc
    style L fill:#fff3cd
Loading

Last reviewed commit: b64d851

Copy link
Contributor

@greptile-apps greptile-apps bot left a comment

Choose a reason for hiding this comment

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

2 files reviewed, 1 comment

Edit Code Review Agent Settings | Greptile

@waleedlatif1 waleedlatif1 merged commit 0ee52df into staging Feb 18, 2026
6 checks passed
@waleedlatif1 waleedlatif1 deleted the cursor/locked-block-outbound-connections-6872 branch February 18, 2026 02:16
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.

3 participants

Comments