From c7ae3efe88c2414ae37b0f489f8a0207973c81d5 Mon Sep 17 00:00:00 2001 From: waleed Date: Fri, 10 Apr 2026 14:35:37 -0700 Subject: [PATCH 1/2] fix(trigger): skip canonical-paired members when validating required fields on deploy --- apps/sim/lib/webhooks/deploy.ts | 41 ++++++++++++++++++++++----------- 1 file changed, 27 insertions(+), 14 deletions(-) diff --git a/apps/sim/lib/webhooks/deploy.ts b/apps/sim/lib/webhooks/deploy.ts index 4a189b681b..f8372e13ce 100644 --- a/apps/sim/lib/webhooks/deploy.ts +++ b/apps/sim/lib/webhooks/deploy.ts @@ -13,6 +13,7 @@ import { } from '@/lib/webhooks/provider-subscriptions' import { getProviderHandler } from '@/lib/webhooks/providers' import { syncWebhooksForCredentialSet } from '@/lib/webhooks/utils.server' +import { buildCanonicalIndex } from '@/lib/workflows/subblocks/visibility' import { getBlock } from '@/blocks' import type { SubBlockConfig } from '@/blocks/types' import type { BlockState } from '@/stores/workflows/workflow/types' @@ -182,20 +183,32 @@ function buildProviderConfig( Object.entries(block.subBlocks || {}).map(([key, value]) => [key, { value: value.value }]) ) - triggerDef.subBlocks - .filter( - (subBlock) => - (subBlock.mode === 'trigger' || subBlock.mode === 'trigger-advanced') && - !SYSTEM_SUBBLOCK_IDS.includes(subBlock.id) - ) - .forEach((subBlock) => { - const valueToUse = getConfigValue(block, subBlock) - if (valueToUse !== null && valueToUse !== undefined && valueToUse !== '') { - providerConfig[subBlock.id] = valueToUse - } else if (isFieldRequired(subBlock, subBlockValues)) { - missingFields.push(subBlock.title || subBlock.id) - } - }) + const canonicalIndex = buildCanonicalIndex(triggerDef.subBlocks) + const satisfiedCanonicalIds = new Set() + + const relevantSubBlocks = triggerDef.subBlocks.filter( + (subBlock) => + (subBlock.mode === 'trigger' || subBlock.mode === 'trigger-advanced') && + !SYSTEM_SUBBLOCK_IDS.includes(subBlock.id) + ) + + for (const subBlock of relevantSubBlocks) { + const valueToUse = getConfigValue(block, subBlock) + if (valueToUse !== null && valueToUse !== undefined && valueToUse !== '') { + providerConfig[subBlock.id] = valueToUse + const canonicalId = canonicalIndex.canonicalIdBySubBlockId[subBlock.id] + if (canonicalId) satisfiedCanonicalIds.add(canonicalId) + } + } + + for (const subBlock of relevantSubBlocks) { + if (providerConfig[subBlock.id] !== undefined) continue + const canonicalId = canonicalIndex.canonicalIdBySubBlockId[subBlock.id] + if (canonicalId && satisfiedCanonicalIds.has(canonicalId)) continue + if (isFieldRequired(subBlock, subBlockValues)) { + missingFields.push(subBlock.title || subBlock.id) + } + } const credentialConfig = triggerDef.subBlocks.find( (subBlock) => subBlock.id === 'triggerCredentials' From 402462a76f92c1455e62ebba794d6c8abc5f22b2 Mon Sep 17 00:00:00 2001 From: waleed Date: Fri, 10 Apr 2026 14:49:39 -0700 Subject: [PATCH 2/2] fix(deploy): track first-pass fills to prevent stale baseConfig bypassing required-field validation Use a dedicated `filledSubBlockIds` Set populated during the first pass so the second-pass skip guard is based solely on live `getConfigValue` results, not on stale entries spread from `baseConfig` (`triggerConfig`). --- apps/sim/lib/webhooks/deploy.ts | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/apps/sim/lib/webhooks/deploy.ts b/apps/sim/lib/webhooks/deploy.ts index f8372e13ce..d460340107 100644 --- a/apps/sim/lib/webhooks/deploy.ts +++ b/apps/sim/lib/webhooks/deploy.ts @@ -185,6 +185,7 @@ function buildProviderConfig( const canonicalIndex = buildCanonicalIndex(triggerDef.subBlocks) const satisfiedCanonicalIds = new Set() + const filledSubBlockIds = new Set() const relevantSubBlocks = triggerDef.subBlocks.filter( (subBlock) => @@ -196,13 +197,14 @@ function buildProviderConfig( const valueToUse = getConfigValue(block, subBlock) if (valueToUse !== null && valueToUse !== undefined && valueToUse !== '') { providerConfig[subBlock.id] = valueToUse + filledSubBlockIds.add(subBlock.id) const canonicalId = canonicalIndex.canonicalIdBySubBlockId[subBlock.id] if (canonicalId) satisfiedCanonicalIds.add(canonicalId) } } for (const subBlock of relevantSubBlocks) { - if (providerConfig[subBlock.id] !== undefined) continue + if (filledSubBlockIds.has(subBlock.id)) continue const canonicalId = canonicalIndex.canonicalIdBySubBlockId[subBlock.id] if (canonicalId && satisfiedCanonicalIds.has(canonicalId)) continue if (isFieldRequired(subBlock, subBlockValues)) {