Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -844,8 +844,13 @@ export const TagDropdown: React.FC<TagDropdownProps> = ({
if (!accessibleBlock) continue

// Skip the current block - blocks cannot reference their own outputs
// Exception: approval blocks can reference their own outputs
if (accessibleBlockId === blockId && accessibleBlock.type !== 'approval') continue
// Exception: approval and human_in_the_loop blocks can reference their own outputs
if (
accessibleBlockId === blockId &&
accessibleBlock.type !== 'approval' &&
accessibleBlock.type !== 'human_in_the_loop'
)
continue
Comment on lines +848 to +853
Copy link
Contributor

Choose a reason for hiding this comment

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

logic: Self-reference exception added for human_in_the_loop, but unlike approval blocks (lines 967-979), there's no corresponding filter to restrict self-references to only the url output. The approval block uses blockTags = isSelfReference ? allTags.filter((tag) => tag.endsWith('.url')) : allTags to prevent circular references.

For human_in_the_loop, when self-referencing, inputFormat fields will also be exposed even though they aren't available at pause time - only url is populated when the block pauses. Consider adding similar handling:

} else if (accessibleBlock.type === 'approval' || accessibleBlock.type === 'human_in_the_loop') {

at line 967, so both block types share the same self-reference filtering logic.

Prompt To Fix With AI
This is a comment left during a code review.
Path: apps/sim/app/workspace/[workspaceId]/w/[workflowId]/components/panel/components/editor/components/sub-block/components/tag-dropdown/tag-dropdown.tsx
Line: 848:853

Comment:
**logic:** Self-reference exception added for `human_in_the_loop`, but unlike `approval` blocks (lines 967-979), there's no corresponding filter to restrict self-references to only the `url` output. The `approval` block uses `blockTags = isSelfReference ? allTags.filter((tag) => tag.endsWith('.url')) : allTags` to prevent circular references.

For `human_in_the_loop`, when self-referencing, inputFormat fields will also be exposed even though they aren't available at pause time - only `url` is populated when the block pauses. Consider adding similar handling:

```
} else if (accessibleBlock.type === 'approval' || accessibleBlock.type === 'human_in_the_loop') {
```

at line 967, so both block types share the same self-reference filtering logic.

How can I resolve this? If you propose a fix, please make it concise.

Copy link
Contributor

Choose a reason for hiding this comment

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

You should reuse the same utility that the approval block uses to filter to only allow url in tag dropdown

Copy link
Contributor

Choose a reason for hiding this comment

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

You're absolutely right! The human_in_the_loop block should use the same filtering logic as the approval block to restrict self-references to only the url output. Looking at the code, I can see that the approval block has proper filtering logic starting at line 967, but the human_in_the_loop block doesn't have this same protection.

Here's the fix to add the same filtering logic for human_in_the_loop blocks:

Suggested change
if (
accessibleBlockId === blockId &&
accessibleBlock.type !== 'approval' &&
accessibleBlock.type !== 'human_in_the_loop'
)
continue
} else if (accessibleBlock.type === 'approval' || accessibleBlock.type === 'human_in_the_loop') {
const dynamicOutputs = getBlockOutputPaths(accessibleBlock.type, mergedSubBlocks)
const isSelfReference = accessibleBlockId === blockId
if (dynamicOutputs.length > 0) {
const allTags = dynamicOutputs.map((path) => `${normalizedBlockName}.${path}`)
blockTags = isSelfReference ? allTags.filter((tag) => tag.endsWith('.url')) : allTags
} else {
const outputPaths = getBlockOutputPaths(accessibleBlock.type, mergedSubBlocks)
const allTags = outputPaths.map((path) => `${normalizedBlockName}.${path}`)
blockTags = isSelfReference ? allTags.filter((tag) => tag.endsWith('.url')) : allTags
}

This change combines both block types into a single condition and applies the same self-reference filtering logic - when a human_in_the_loop block references itself, only tags ending with .url will be available, preventing circular references while still allowing access to the resume URL during pause time.


const blockConfig = getBlock(accessibleBlock.type)

Expand Down Expand Up @@ -972,6 +977,8 @@ export const TagDropdown: React.FC<TagDropdownProps> = ({
const allTags = outputPaths.map((path) => `${normalizedBlockName}.${path}`)
blockTags = isSelfReference ? allTags.filter((tag) => tag.endsWith('.url')) : allTags
}
} else if (accessibleBlock.type === 'human_in_the_loop') {
blockTags = [`${normalizedBlockName}.url`]
} else {
const operationValue =
mergedSubBlocks?.operation?.value ?? getSubBlockValue(accessibleBlockId, 'operation')
Expand Down
7 changes: 7 additions & 0 deletions apps/sim/lib/workflows/blocks/block-outputs.ts
Original file line number Diff line number Diff line change
Expand Up @@ -225,6 +225,13 @@ export function getBlockOutputs(
return getUnifiedStartOutputs(subBlocks)
}

if (blockType === 'human_in_the_loop') {
// For human_in_the_loop, only expose url (inputFormat fields are only available after resume)
return {
url: { type: 'string', description: 'Resume UI URL' },
}
}

if (blockType === 'approval') {
// Start with only url (apiUrl commented out - not accessible as output)
const pauseResumeOutputs: Record<string, any> = {
Expand Down
Loading