diff --git a/apps/sim/app/workspace/[workspaceId]/w/[workflowId]/utils/block-protection-utils.ts b/apps/sim/app/workspace/[workspaceId]/w/[workflowId]/utils/block-protection-utils.ts index 8380dd985..797c7f2c9 100644 --- a/apps/sim/app/workspace/[workspaceId]/w/[workflowId]/utils/block-protection-utils.ts +++ b/apps/sim/app/workspace/[workspaceId]/w/[workflowId]/utils/block-protection-utils.ts @@ -71,20 +71,6 @@ export function filterProtectedBlocks( } } -/** - * Filters edges to only include those that are not protected. - * - * @param edges - Array of edges to filter - * @param blocks - Record of all blocks in the workflow - * @returns Array of edges that can be modified (not protected) - */ -export function filterUnprotectedEdges( - edges: T[], - blocks: Record -): T[] { - return edges.filter((edge) => !isEdgeProtected(edge, blocks)) -} - /** * Checks if any blocks in the selection are protected. * Useful for determining if edit actions should be disabled. diff --git a/apps/sim/lib/copilot/tools/server/workflow/edit-workflow.ts b/apps/sim/lib/copilot/tools/server/workflow/edit-workflow.ts index d4fe120cf..54080236d 100644 --- a/apps/sim/lib/copilot/tools/server/workflow/edit-workflow.ts +++ b/apps/sim/lib/copilot/tools/server/workflow/edit-workflow.ts @@ -2146,6 +2146,19 @@ function applyOperationsToWorkflowState( // Handle nested nodes (for loops/parallels created from scratch) if (params.nestedNodes) { + // Defensive check: verify parent is not locked before adding children + // (Parent was just created with locked: false, but check for consistency) + const parentBlock = modifiedState.blocks[block_id] + if (parentBlock?.locked) { + logSkippedItem(skippedItems, { + type: 'block_locked', + operationType: 'add_nested_nodes', + blockId: block_id, + reason: `Container "${block_id}" is locked - cannot add nested nodes`, + }) + break + } + Object.entries(params.nestedNodes).forEach(([childId, childBlock]: [string, any]) => { // Validate childId is a valid string if (!isValidKey(childId)) { diff --git a/apps/sim/stores/workflows/workflow/store.ts b/apps/sim/stores/workflows/workflow/store.ts index 3e28d717b..e58228ff3 100644 --- a/apps/sim/stores/workflows/workflow/store.ts +++ b/apps/sim/stores/workflows/workflow/store.ts @@ -373,16 +373,16 @@ export const useWorkflowStore = create()( const newBlocks = { ...currentBlocks } const blocksToToggle = new Set() - // For each ID, collect blocks to toggle (skip locked blocks) + // For each ID, collect blocks to toggle (skip locked blocks entirely) // If it's a container, also include non-locked children for (const id of ids) { const block = currentBlocks[id] if (!block) continue - // Skip locked blocks - if (!block.locked) { - blocksToToggle.add(id) - } + // Skip locked blocks entirely (including their children) + if (block.locked) continue + + blocksToToggle.add(id) // If it's a loop or parallel, also include non-locked children if (block.type === 'loop' || block.type === 'parallel') {