Skip to content

[Bug] Timeline UI goes blank when DO_WHILE loop contains SWITCH defaultCase or FORK_JOIN_DYNAMIC tasks #534

@pinyiw

Description

@pinyiw

Describe the bug
When a DO_WHILE loop contains a SWITCH task (with execution entering the defaultCase) or FORK_JOIN_DYNAMIC tasks, the timeline view in the Conductor UI fails to render and appears blank.

Details
Conductor version: v3.21.15
Persistence implementation: Postgres
Queue implementation: Postgres
Lock: Redis
Workflow definition for SWITCH task:

{
  "createTime": 1750729588107,
  "updateTime": 1750729654933,
  "name": "TestWhileSwitchDefaultBug",
  "description": "Edit or extend this sample workflow. Set the workflow name to get started",
  "version": 1,
  "tasks": [
    {
      "name": "do_while_ref",
      "taskReferenceName": "do_while_ref",
      "inputParameters": {
        "loop_limit": 2
      },
      "type": "DO_WHILE",
      "decisionCases": {},
      "defaultCase": [],
      "forkTasks": [],
      "startDelay": 0,
      "joinOn": [],
      "optional": false,
      "defaultExclusiveJoinTask": [],
      "asyncComplete": false,
      "loopCondition": "(function () {if ($.do_while_ref['iteration'] < $.loop_limit) {return true;} return false;})();",
      "loopOver": [
        {
          "name": "switch_ref",
          "taskReferenceName": "switch_ref",
          "inputParameters": {
            "decision_case": "default"
          },
          "type": "SWITCH",
          "decisionCases": {
            "dummy": [
              {
                "name": "dummy_decision_ref",
                "taskReferenceName": "dummy_decision_ref",
                "inputParameters": {
                  "dummy": "true"
                },
                "type": "SET_VARIABLE",
                "decisionCases": {},
                "defaultCase": [],
                "forkTasks": [],
                "startDelay": 0,
                "joinOn": [],
                "optional": false,
                "defaultExclusiveJoinTask": [],
                "asyncComplete": false,
                "loopOver": [],
                "onStateChange": {},
                "permissive": false
              }
            ]
          },
          "defaultCase": [
            {
              "name": "dummy_default_ref",
              "taskReferenceName": "dummy_default_ref",
              "inputParameters": {
                "dummy": "true"
              },
              "type": "SET_VARIABLE",
              "decisionCases": {},
              "defaultCase": [],
              "forkTasks": [],
              "startDelay": 0,
              "joinOn": [],
              "optional": false,
              "defaultExclusiveJoinTask": [],
              "asyncComplete": false,
              "loopOver": [],
              "onStateChange": {},
              "permissive": false
            }
          ],
          "forkTasks": [],
          "startDelay": 0,
          "joinOn": [],
          "optional": false,
          "defaultExclusiveJoinTask": [],
          "asyncComplete": false,
          "loopOver": [],
          "evaluatorType": "value-param",
          "expression": "decision_case",
          "onStateChange": {},
          "permissive": false
        }
      ],
      "evaluatorType": "javascript",
      "onStateChange": {},
      "permissive": false
    }
  ],
  "inputParameters": [],
  "outputParameters": {},
  "schemaVersion": 2,
  "restartable": true,
  "workflowStatusListenerEnabled": false,
  "ownerEmail": "[email protected]",
  "timeoutPolicy": "ALERT_ONLY",
  "timeoutSeconds": 0,
  "variables": {},
  "inputTemplate": {},
  "enforceSchema": true
}

Workflow definition for FORK_JOIN_DYNAMIC task:

{
  "createTime": 1750729849968,
  "updateTime": 1750730116303,
  "name": "TestWhileForkJoinDynamicBug",
  "description": "Edit or extend this sample workflow. Set the workflow name to get started",
  "version": 1,
  "tasks": [
    {
      "name": "do_while_ref",
      "taskReferenceName": "do_while_ref",
      "inputParameters": {
        "loop_limit": 2
      },
      "type": "DO_WHILE",
      "decisionCases": {},
      "defaultCase": [],
      "forkTasks": [],
      "startDelay": 0,
      "joinOn": [],
      "optional": false,
      "defaultExclusiveJoinTask": [],
      "asyncComplete": false,
      "loopCondition": "(function () {if ($.do_while_ref['iteration'] < $.loop_limit) {return true;} return false;})();",
      "loopOver": [
        {
          "name": "prepare_fork_input_ref",
          "taskReferenceName": "prepare_fork_input_ref",
          "inputParameters": {
            "queryExpression": "[{dummy: true}, {dummy: false}]"
          },
          "type": "JSON_JQ_TRANSFORM",
          "decisionCases": {},
          "defaultCase": [],
          "forkTasks": [],
          "startDelay": 0,
          "joinOn": [],
          "optional": false,
          "defaultExclusiveJoinTask": [],
          "asyncComplete": false,
          "loopOver": [],
          "onStateChange": {},
          "permissive": false
        },
        {
          "name": "dynamic_fork_ref",
          "taskReferenceName": "dynamic_fork_ref",
          "inputParameters": {
            "forkTaskName": "dummy",
            "forkTaskType": "SET_VARIABLE",
            "forkTaskInputs": "${prepare_fork_input_ref.output.result}"
          },
          "type": "FORK_JOIN_DYNAMIC",
          "decisionCases": {},
          "dynamicForkTasksParam": "dynamicTasks",
          "dynamicForkTasksInputParamName": "dynamicTasksInput",
          "defaultCase": [],
          "forkTasks": [],
          "startDelay": 0,
          "joinOn": [],
          "optional": false,
          "defaultExclusiveJoinTask": [],
          "asyncComplete": false,
          "loopOver": [],
          "onStateChange": {},
          "permissive": false
        },
        {
          "name": "join_ref",
          "taskReferenceName": "join_ref",
          "inputParameters": {},
          "type": "JOIN",
          "decisionCases": {},
          "defaultCase": [],
          "forkTasks": [],
          "startDelay": 0,
          "joinOn": [],
          "optional": false,
          "defaultExclusiveJoinTask": [],
          "asyncComplete": false,
          "loopOver": [],
          "onStateChange": {},
          "permissive": false
        }
      ],
      "evaluatorType": "javascript",
      "onStateChange": {},
      "permissive": false
    }
  ],
  "inputParameters": [],
  "outputParameters": {},
  "schemaVersion": 2,
  "restartable": true,
  "workflowStatusListenerEnabled": false,
  "ownerEmail": "[email protected]",
  "timeoutPolicy": "ALERT_ONLY",
  "timeoutSeconds": 0,
  "variables": {},
  "inputTemplate": {},
  "enforceSchema": true
}

To Reproduce
Steps to reproduce the behavior:

  1. Start a workflow execution with either of the workflows above (no input needed).
  2. Open the execution page.
  3. Click on the Timeline tab under the Tasks tab.
  4. The page will go blank.

Expected behavior
The timeline UI should work correctly.

Screenshots
SWITCH workflow execution

DYNAMIC_FORK_JOIN execution

Metadata

Metadata

Assignees

Labels

bugSomething isn't working

Type

Projects

Status

In Progress

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions