From 0b5de3645ece6c748bf08536c4e2af93f5b7dc3d Mon Sep 17 00:00:00 2001 From: Vikhyath Mondreti Date: Tue, 16 Dec 2025 13:44:38 -0800 Subject: [PATCH 1/3] fix(serializer): condition check should check if any condition are met --- apps/sim/serializer/index.ts | 60 +++++++++++++++++++++++------------- 1 file changed, 39 insertions(+), 21 deletions(-) diff --git a/apps/sim/serializer/index.ts b/apps/sim/serializer/index.ts index db9401824c..3badfcc3a8 100644 --- a/apps/sim/serializer/index.ts +++ b/apps/sim/serializer/index.ts @@ -402,8 +402,8 @@ export class Serializer { // Second pass: filter by mode and conditions Object.entries(block.subBlocks).forEach(([id, subBlock]) => { - // Find the corresponding subblock config to check its mode and condition - const subBlockConfig = blockConfig.subBlocks.find((config) => config.id === id) + // Find ALL subblock configs with this ID (there may be multiple with different conditions) + const matchingConfigs = blockConfig.subBlocks.filter((config) => config.id === id) // Include field if it matches current mode OR if it's the starter inputFormat with values const hasStarterInputFormatValues = @@ -417,13 +417,20 @@ export class Serializer { const isLegacyAgentField = isAgentBlock && ['systemPrompt', 'userPrompt', 'memories'].includes(id) - // Check if field's condition is met (conditionally-hidden fields should be excluded) - const conditionMet = subBlockConfig - ? evaluateCondition(subBlockConfig.condition, allValues) - : true + // Check if ANY matching config's condition is met (for fields with same ID but different conditions) + // This handles blocks like Google Sheets where "values" field appears multiple times + // with different operation conditions (write, update, append) + const anyConditionMet = + matchingConfigs.length === 0 + ? true + : matchingConfigs.some( + (config) => + shouldIncludeField(config, isAdvancedMode) && + evaluateCondition(config.condition, allValues) + ) if ( - (subBlockConfig && shouldIncludeField(subBlockConfig, isAdvancedMode) && conditionMet) || + (matchingConfigs.length > 0 && anyConditionMet) || hasStarterInputFormatValues || isLegacyAgentField ) { @@ -540,26 +547,31 @@ export class Serializer { // Iterate through the tool's parameters, not the block's subBlocks Object.entries(currentTool.params || {}).forEach(([paramId, paramConfig]) => { if (paramConfig.required && paramConfig.visibility === 'user-only') { - const subBlockConfig = blockConfig.subBlocks?.find((sb: any) => sb.id === paramId) + // Find ALL subblock configs with this ID (there may be multiple with different conditions) + const matchingConfigs = blockConfig.subBlocks?.filter((sb: any) => sb.id === paramId) || [] let shouldValidateParam = true - if (subBlockConfig) { + if (matchingConfigs.length > 0) { const isAdvancedMode = block.advancedMode ?? false - const includedByMode = shouldIncludeField(subBlockConfig, isAdvancedMode) - // Check visibility condition - const includedByCondition = evaluateCondition(subBlockConfig.condition, params) + // Check if ANY matching config's condition is met and requires validation + shouldValidateParam = matchingConfigs.some((subBlockConfig: any) => { + const includedByMode = shouldIncludeField(subBlockConfig, isAdvancedMode) - // Check if field is required based on its required condition (if it's a condition object) - const isRequired = (() => { - if (!subBlockConfig.required) return false - if (typeof subBlockConfig.required === 'boolean') return subBlockConfig.required - // If required is a condition object, evaluate it - return evaluateCondition(subBlockConfig.required, params) - })() + // Check visibility condition + const includedByCondition = evaluateCondition(subBlockConfig.condition, params) - shouldValidateParam = includedByMode && includedByCondition && isRequired + // Check if field is required based on its required condition (if it's a condition object) + const isRequired = (() => { + if (!subBlockConfig.required) return false + if (typeof subBlockConfig.required === 'boolean') return subBlockConfig.required + // If required is a condition object, evaluate it + return evaluateCondition(subBlockConfig.required, params) + })() + + return includedByMode && includedByCondition && isRequired + }) } if (!shouldValidateParam) { @@ -568,7 +580,13 @@ export class Serializer { const fieldValue = params[paramId] if (fieldValue === undefined || fieldValue === null || fieldValue === '') { - const displayName = subBlockConfig?.title || paramId + // Find the first matching config with a met condition for the display name + const activeConfig = matchingConfigs.find( + (config: any) => + shouldIncludeField(config, block.advancedMode ?? false) && + evaluateCondition(config.condition, params) + ) + const displayName = activeConfig?.title || paramId missingFields.push(displayName) } } From e5227e887977561921c04fbc22ae608d1c38573d Mon Sep 17 00:00:00 2001 From: Vikhyath Mondreti Date: Tue, 16 Dec 2025 13:55:22 -0800 Subject: [PATCH 2/3] remove comments --- apps/sim/serializer/index.ts | 8 -------- 1 file changed, 8 deletions(-) diff --git a/apps/sim/serializer/index.ts b/apps/sim/serializer/index.ts index 3badfcc3a8..9612645103 100644 --- a/apps/sim/serializer/index.ts +++ b/apps/sim/serializer/index.ts @@ -547,7 +547,6 @@ export class Serializer { // Iterate through the tool's parameters, not the block's subBlocks Object.entries(currentTool.params || {}).forEach(([paramId, paramConfig]) => { if (paramConfig.required && paramConfig.visibility === 'user-only') { - // Find ALL subblock configs with this ID (there may be multiple with different conditions) const matchingConfigs = blockConfig.subBlocks?.filter((sb: any) => sb.id === paramId) || [] let shouldValidateParam = true @@ -555,18 +554,14 @@ export class Serializer { if (matchingConfigs.length > 0) { const isAdvancedMode = block.advancedMode ?? false - // Check if ANY matching config's condition is met and requires validation shouldValidateParam = matchingConfigs.some((subBlockConfig: any) => { const includedByMode = shouldIncludeField(subBlockConfig, isAdvancedMode) - // Check visibility condition const includedByCondition = evaluateCondition(subBlockConfig.condition, params) - // Check if field is required based on its required condition (if it's a condition object) const isRequired = (() => { if (!subBlockConfig.required) return false if (typeof subBlockConfig.required === 'boolean') return subBlockConfig.required - // If required is a condition object, evaluate it return evaluateCondition(subBlockConfig.required, params) })() @@ -580,7 +575,6 @@ export class Serializer { const fieldValue = params[paramId] if (fieldValue === undefined || fieldValue === null || fieldValue === '') { - // Find the first matching config with a met condition for the display name const activeConfig = matchingConfigs.find( (config: any) => shouldIncludeField(config, block.advancedMode ?? false) && @@ -614,8 +608,6 @@ export class Serializer { const accessibleIds = new Set(ancestorIds) accessibleIds.add(blockId) - // Only add starter block if it's actually upstream (already in ancestorIds) - // Don't add it just because it exists on the canvas if (starterBlock && ancestorIds.includes(starterBlock.id)) { accessibleIds.add(starterBlock.id) } From 7fef3319f135fcd8d38f886a9df69b0103f8ef61 Mon Sep 17 00:00:00 2001 From: Vikhyath Mondreti Date: Tue, 16 Dec 2025 13:56:17 -0800 Subject: [PATCH 3/3] remove more comments --- apps/sim/serializer/index.ts | 4 ---- 1 file changed, 4 deletions(-) diff --git a/apps/sim/serializer/index.ts b/apps/sim/serializer/index.ts index 9612645103..6500f7fb22 100644 --- a/apps/sim/serializer/index.ts +++ b/apps/sim/serializer/index.ts @@ -402,7 +402,6 @@ export class Serializer { // Second pass: filter by mode and conditions Object.entries(block.subBlocks).forEach(([id, subBlock]) => { - // Find ALL subblock configs with this ID (there may be multiple with different conditions) const matchingConfigs = blockConfig.subBlocks.filter((config) => config.id === id) // Include field if it matches current mode OR if it's the starter inputFormat with values @@ -417,9 +416,6 @@ export class Serializer { const isLegacyAgentField = isAgentBlock && ['systemPrompt', 'userPrompt', 'memories'].includes(id) - // Check if ANY matching config's condition is met (for fields with same ID but different conditions) - // This handles blocks like Google Sheets where "values" field appears multiple times - // with different operation conditions (write, update, append) const anyConditionMet = matchingConfigs.length === 0 ? true