@@ -991,6 +991,46 @@ describe('Serializer', () => {
991991 expect ( slackBlock ?. config . params . unknownField ) . toBeUndefined ( )
992992 } )
993993
994+ it . concurrent (
995+ 'should include conditional fields when condition field has default value but null stored value' ,
996+ ( ) => {
997+ const serializer = new Serializer ( )
998+
999+ // This simulates the cursor block scenario where:
1000+ // - operation has a default value function: () => 'cursor_launch_agent'
1001+ // - branchName has condition: { field: 'operation', value: 'cursor_launch_agent' }
1002+ // - But operation's stored value is null (user never changed the dropdown)
1003+ // We'll use slack block which has similar conditional field behavior
1004+ const slackBlockWithNullChannel : any = {
1005+ id : 'slack-1' ,
1006+ type : 'slack' ,
1007+ name : 'Slack' ,
1008+ position : { x : 0 , y : 0 } ,
1009+ advancedMode : false ,
1010+ subBlocks : {
1011+ channel : { value : 'general' } , // This simulates the 'operation' dropdown
1012+ text : { value : 'Hello world' } , // This has a condition on channel
1013+ // manualChannel would be null as it's in advanced mode
1014+ } ,
1015+ outputs : { } ,
1016+ enabled : true ,
1017+ }
1018+
1019+ const serialized = serializer . serializeWorkflow (
1020+ { 'slack-1' : slackBlockWithNullChannel } ,
1021+ [ ] ,
1022+ { }
1023+ )
1024+
1025+ const slackBlock = serialized . blocks . find ( ( b ) => b . id === 'slack-1' )
1026+ expect ( slackBlock ) . toBeDefined ( )
1027+
1028+ // Both fields should be included since channel (the condition field) has a value
1029+ expect ( slackBlock ?. config . params . channel ) . toBe ( 'general' )
1030+ expect ( slackBlock ?. config . params . text ) . toBe ( 'Hello world' )
1031+ }
1032+ )
1033+
9941034 it . concurrent (
9951035 'should preserve legacy agent fields (systemPrompt, userPrompt, memories) for backward compatibility' ,
9961036 ( ) => {
0 commit comments