@@ -13,6 +13,7 @@ import {
1313} from '@/lib/webhooks/provider-subscriptions'
1414import { getProviderHandler } from '@/lib/webhooks/providers'
1515import { syncWebhooksForCredentialSet } from '@/lib/webhooks/utils.server'
16+ import { buildCanonicalIndex } from '@/lib/workflows/subblocks/visibility'
1617import { getBlock } from '@/blocks'
1718import type { SubBlockConfig } from '@/blocks/types'
1819import type { BlockState } from '@/stores/workflows/workflow/types'
@@ -181,23 +182,40 @@ function buildProviderConfig(
181182 Object . entries ( block . subBlocks || { } ) . map ( ( [ key , value ] ) => [ key , { value : value . value } ] )
182183 )
183184
184- triggerDef . subBlocks
185- . filter (
186- ( subBlock ) =>
187- ( subBlock . mode === 'trigger' || subBlock . mode === 'trigger-advanced' ) &&
188- ! SYSTEM_SUBBLOCK_IDS . includes ( subBlock . id )
189- )
190- . forEach ( ( subBlock ) => {
191- const valueToUse = getConfigValue ( block , subBlock )
192- if ( valueToUse !== null && valueToUse !== undefined && valueToUse !== '' ) {
193- providerConfig [ subBlock . id ] = valueToUse
194- } else {
195- delete providerConfig [ subBlock . id ]
196- if ( isFieldRequired ( subBlock , subBlockValues ) ) {
197- missingFields . push ( subBlock . title || subBlock . id )
198- }
199- }
200- } )
185+ const canonicalIndex = buildCanonicalIndex ( triggerDef . subBlocks )
186+ const satisfiedCanonicalIds = new Set < string > ( )
187+ const filledSubBlockIds = new Set < string > ( )
188+
189+ const relevantSubBlocks = triggerDef . subBlocks . filter (
190+ ( subBlock ) =>
191+ ( subBlock . mode === 'trigger' || subBlock . mode === 'trigger-advanced' ) &&
192+ ! SYSTEM_SUBBLOCK_IDS . includes ( subBlock . id )
193+ )
194+
195+ // First pass: populate providerConfig, clear stale baseConfig entries, and track which
196+ // subblocks and canonical groups have a value.
197+ for ( const subBlock of relevantSubBlocks ) {
198+ const valueToUse = getConfigValue ( block , subBlock )
199+ if ( valueToUse !== null && valueToUse !== undefined && valueToUse !== '' ) {
200+ providerConfig [ subBlock . id ] = valueToUse
201+ filledSubBlockIds . add ( subBlock . id )
202+ const canonicalId = canonicalIndex . canonicalIdBySubBlockId [ subBlock . id ]
203+ if ( canonicalId ) satisfiedCanonicalIds . add ( canonicalId )
204+ } else {
205+ delete providerConfig [ subBlock . id ]
206+ }
207+ }
208+
209+ // Second pass: validate required fields. Skip subblocks that are filled or whose canonical
210+ // group is satisfied by another member.
211+ for ( const subBlock of relevantSubBlocks ) {
212+ if ( filledSubBlockIds . has ( subBlock . id ) ) continue
213+ const canonicalId = canonicalIndex . canonicalIdBySubBlockId [ subBlock . id ]
214+ if ( canonicalId && satisfiedCanonicalIds . has ( canonicalId ) ) continue
215+ if ( isFieldRequired ( subBlock , subBlockValues ) ) {
216+ missingFields . push ( subBlock . title || subBlock . id )
217+ }
218+ }
201219
202220 const credentialConfig = triggerDef . subBlocks . find (
203221 ( subBlock ) => subBlock . id === 'triggerCredentials'
0 commit comments