Workflow replayer not working with child workflow when a non-static ID is provided

func SampleChildWorkflow(ctx workflow.Context, name string) (string, error) {
	logger := workflow.GetLogger(ctx)
	greeting := "Hello " + name + "!"
	logger.Info("Child workflow execution: " + greeting)
	return greeting, nil
}

func SampleParentWorkflow(ctx workflow.Context) (string, error) {
  logger := workflow.GetLogger(ctx)
  childId := workflow.GetInfo(ctx).WorkflowExecution.ID
  cwo := workflow.ChildWorkflowOptions{
    WorkflowID: childId + "ABC-SIMPLE-CHILD-WORKFLOW-ID",
  }
  ctx = workflow.WithChildOptions(ctx, cwo)

  var result string
  err := workflow.ExecuteChildWorkflow(ctx, SampleChildWorkflow, "World").Get(ctx, &result)
  if err != nil {
    logger.Error("Parent execution received child execution failure.", "Error", err)
    return "", err
  }

  logger.Info("Parent execution completed.", "Result", result)
  return result, nil
}

Replayer test

func Test_Replay(t *testing.T) {
  replayer := worker.NewWorkflowReplayer()

  replayer.RegisterWorkflow(child_workflow.SampleParentWorkflow)
  replayer.RegisterWorkflow(child_workflow.SampleChildWorkflow)

  err := replayer.ReplayWorkflowHistoryFromJSONFile(nil, "test_events.json")
  require.NoError(t, err)
}

This is a small variation of the temporal child workflow example. The only difference is that, in the original code the child’s workflow ID is static(ABC-SIMPLE-CHILD-WORKFLOW-ID). In this example, it’s prefixed with the parent workflow ID.

Running the replayer on the event history is throwing the follow error.

2023/08/24 14:19:06 INFO  No DataConverter configured for temporal worker. Use default one.
2023/08/24 14:19:06 ERROR Workflow panic WorkflowType SampleParentWorkflow WorkflowID ReplayId RunID 8b8f180e-1884-448e-9f52-048a67a4a93f Attempt 1 Error unknown command CommandType: ChildWorkflow, ID: parent-workflow_c1ae1b05-3906-452b-9da1-f3672429f987ABC-SIMPLE-CHILD-WORKFLOW-ID, possible causes are nondeterministic workflow definition code or incompatible change in the workflow definition StackTrace process event for child-workflow [panic]:
go.temporal.io/sdk/internal.panicIllegalState(...)
....
....
Received unexpected error:
        	            	unknown command CommandType: ChildWorkflow, ID: parent-workflow_c1ae1b05-3906-452b-9da1-f3672429f987ABC-SIMPLE-CHILD-WORKFLOW-ID, possible causes are nondeterministic workflow definition code or incompatible change in the workflow definition

It looks like the reason for this the replayer is always using the WorkflowID as ‘ReplayID’ and the child workflow’s ID in the event history is not matching with what’s expected.

Please note that if the I remove the child workflow ID in the ChildOptions, the replayer succeeds.

Please let me know if this is a bug in the replayer logic or am I using the options incorrectly?

Event history

{
  "events": [
    {
      "eventId": "1",
      "eventTime": "2023-08-24T01:12:23.594594203Z",
      "eventType": "WorkflowExecutionStarted",
      "version": "0",
      "taskId": "1048587",
      "workerMayIgnore": false,
      "workflowExecutionStartedEventAttributes": {
        "workflowType": {
          "name": "SampleParentWorkflow"
        },
        "parentWorkflowNamespace": "",
        "parentWorkflowNamespaceId": "",
        "parentWorkflowExecution": null,
        "parentInitiatedEventId": "0",
        "taskQueue": {
          "name": "child-workflow",
          "kind": "Normal",
          "normalName": ""
        },
        "input": null,
        "workflowExecutionTimeout": "0s",
        "workflowRunTimeout": "0s",
        "workflowTaskTimeout": "10s",
        "continuedExecutionRunId": "",
        "initiator": "Unspecified",
        "continuedFailure": null,
        "lastCompletionResult": null,
        "originalExecutionRunId": "8b8f180e-1884-448e-9f52-048a67a4a93f",
        "identity": "1531553@U22-SAC0130-ENG@",
        "firstExecutionRunId": "8b8f180e-1884-448e-9f52-048a67a4a93f",
        "retryPolicy": null,
        "attempt": 1,
        "workflowExecutionExpirationTime": null,
        "cronSchedule": "",
        "firstWorkflowTaskBackoff": "0s",
        "memo": null,
        "searchAttributes": null,
        "prevAutoResetPoints": null,
        "header": {
          "fields": {}
        },
        "parentInitiatedEventVersion": "0",
        "workflowId": "parent-workflow_c1ae1b05-3906-452b-9da1-f3672429f987",
        "sourceVersionStamp": null
      }
    },
    {
      "eventId": "2",
      "eventTime": "2023-08-24T01:12:23.594638364Z",
      "eventType": "WorkflowTaskScheduled",
      "version": "0",
      "taskId": "1048588",
      "workerMayIgnore": false,
      "workflowTaskScheduledEventAttributes": {
        "taskQueue": {
          "name": "child-workflow",
          "kind": "Normal",
          "normalName": ""
        },
        "startToCloseTimeout": "10s",
        "attempt": 1
      }
    },
    {
      "eventId": "3",
      "eventTime": "2023-08-24T01:12:23.600005969Z",
      "eventType": "WorkflowTaskStarted",
      "version": "0",
      "taskId": "1048593",
      "workerMayIgnore": false,
      "workflowTaskStartedEventAttributes": {
        "scheduledEventId": "2",
        "identity": "1530111@U22-SAC0130-ENG@",
        "requestId": "5f6b6284-afd8-4998-aabe-b7c685da6c73",
        "suggestContinueAsNew": false,
        "historySizeBytes": "299"
      }
    },
    {
      "eventId": "4",
      "eventTime": "2023-08-24T01:12:23.604668513Z",
      "eventType": "WorkflowTaskCompleted",
      "version": "0",
      "taskId": "1048597",
      "workerMayIgnore": false,
      "workflowTaskCompletedEventAttributes": {
        "scheduledEventId": "2",
        "startedEventId": "3",
        "identity": "1530111@U22-SAC0130-ENG@",
        "binaryChecksum": "",
        "workerVersion": {
          "buildId": "0e18cf99ce54c91bcc93ba0861d7d3d9",
          "bundleId": "",
          "useVersioning": false
        },
        "sdkMetadata": {
          "coreUsedFlags": [],
          "langUsedFlags": [
            3
          ]
        },
        "meteringMetadata": {
          "nonfirstLocalActivityExecutionAttempts": 0
        }
      }
    },
    {
      "eventId": "5",
      "eventTime": "2023-08-24T01:12:23.605160638Z",
      "eventType": "StartChildWorkflowExecutionInitiated",
      "version": "0",
      "taskId": "1048598",
      "workerMayIgnore": false,
      "startChildWorkflowExecutionInitiatedEventAttributes": {
        "namespace": "default",
        "namespaceId": "d9d1cae7-ac83-41f2-b65f-bba5ae47de88",
        "workflowId": "parent-workflow_c1ae1b05-3906-452b-9da1-f3672429f987ABC-SIMPLE-CHILD-WORKFLOW-ID",
        "workflowType": {
          "name": "SampleChildWorkflow"
        },
        "taskQueue": {
          "name": "child-workflow",
          "kind": "Normal",
          "normalName": ""
        },
        "input": {
          "payloads": [
            {
              "metadata": {
                "encoding": "anNvbi9wbGFpbg=="
              },
              "data": "IldvcmxkIg=="
            }
          ]
        },
        "workflowExecutionTimeout": "0s",
        "workflowRunTimeout": "0s",
        "workflowTaskTimeout": "10s",
        "parentClosePolicy": "Terminate",
        "control": "",
        "workflowTaskCompletedEventId": "4",
        "workflowIdReusePolicy": "AllowDuplicate",
        "retryPolicy": null,
        "cronSchedule": "",
        "header": {
          "fields": {}
        },
        "memo": null,
        "searchAttributes": null,
        "useCompatibleVersion": true
      }
    },
    {
      "eventId": "6",
      "eventTime": "2023-08-24T01:12:23.610478203Z",
      "eventType": "ChildWorkflowExecutionStarted",
      "version": "0",
      "taskId": "1048606",
      "workerMayIgnore": false,
      "childWorkflowExecutionStartedEventAttributes": {
        "namespace": "default",
        "namespaceId": "d9d1cae7-ac83-41f2-b65f-bba5ae47de88",
        "initiatedEventId": "5",
        "workflowExecution": {
          "workflowId": "parent-workflow_c1ae1b05-3906-452b-9da1-f3672429f987ABC-SIMPLE-CHILD-WORKFLOW-ID",
          "runId": "8dcff8d1-991e-42ae-9b16-58b85add4856"
        },
        "workflowType": {
          "name": "SampleChildWorkflow"
        },
        "header": {
          "fields": {}
        }
      }
    },
    {
      "eventId": "7",
      "eventTime": "2023-08-24T01:12:23.610490793Z",
      "eventType": "WorkflowTaskScheduled",
      "version": "0",
      "taskId": "1048607",
      "workerMayIgnore": false,
      "workflowTaskScheduledEventAttributes": {
        "taskQueue": {
          "name": "U22-SAC0130-ENG:567eb80c-5fa5-46d4-a392-8b4069affabf",
          "kind": "Sticky",
          "normalName": "child-workflow"
        },
        "startToCloseTimeout": "10s",
        "attempt": 1
      }
    },
    {
      "eventId": "8",
      "eventTime": "2023-08-24T01:12:23.612523743Z",
      "eventType": "WorkflowTaskStarted",
      "version": "0",
      "taskId": "1048615",
      "workerMayIgnore": false,
      "workflowTaskStartedEventAttributes": {
        "scheduledEventId": "7",
        "identity": "1530111@U22-SAC0130-ENG@",
        "requestId": "0fce767b-0c37-4dda-a0d3-a702c4b2e8d8",
        "suggestContinueAsNew": false,
        "historySizeBytes": "1082"
      }
    },
    {
      "eventId": "9",
      "eventTime": "2023-08-24T01:12:23.617848125Z",
      "eventType": "WorkflowTaskCompleted",
      "version": "0",
      "taskId": "1048630",
      "workerMayIgnore": false,
      "workflowTaskCompletedEventAttributes": {
        "scheduledEventId": "7",
        "startedEventId": "8",
        "identity": "1530111@U22-SAC0130-ENG@",
        "binaryChecksum": "",
        "workerVersion": {
          "buildId": "0e18cf99ce54c91bcc93ba0861d7d3d9",
          "bundleId": "",
          "useVersioning": false
        },
        "sdkMetadata": {
          "coreUsedFlags": [],
          "langUsedFlags": []
        },
        "meteringMetadata": {
          "nonfirstLocalActivityExecutionAttempts": 0
        }
      }
    },
    {
      "eventId": "10",
      "eventTime": "2023-08-24T01:12:23.620046200Z",
      "eventType": "ChildWorkflowExecutionCompleted",
      "version": "0",
      "taskId": "1048632",
      "workerMayIgnore": false,
      "childWorkflowExecutionCompletedEventAttributes": {
        "result": {
          "payloads": [
            {
              "metadata": {
                "encoding": "anNvbi9wbGFpbg=="
              },
              "data": "IkhlbGxvIFdvcmxkISI="
            }
          ]
        },
        "namespace": "default",
        "namespaceId": "d9d1cae7-ac83-41f2-b65f-bba5ae47de88",
        "workflowExecution": {
          "workflowId": "parent-workflow_c1ae1b05-3906-452b-9da1-f3672429f987ABC-SIMPLE-CHILD-WORKFLOW-ID",
          "runId": "8dcff8d1-991e-42ae-9b16-58b85add4856"
        },
        "workflowType": {
          "name": "SampleChildWorkflow"
        },
        "initiatedEventId": "5",
        "startedEventId": "6"
      }
    },
    {
      "eventId": "11",
      "eventTime": "2023-08-24T01:12:23.620051374Z",
      "eventType": "WorkflowTaskScheduled",
      "version": "0",
      "taskId": "1048633",
      "workerMayIgnore": false,
      "workflowTaskScheduledEventAttributes": {
        "taskQueue": {
          "name": "U22-SAC0130-ENG:567eb80c-5fa5-46d4-a392-8b4069affabf",
          "kind": "Sticky",
          "normalName": "child-workflow"
        },
        "startToCloseTimeout": "10s",
        "attempt": 1
      }
    },
    {
      "eventId": "12",
      "eventTime": "2023-08-24T01:12:23.621608153Z",
      "eventType": "WorkflowTaskStarted",
      "version": "0",
      "taskId": "1048637",
      "workerMayIgnore": false,
      "workflowTaskStartedEventAttributes": {
        "scheduledEventId": "11",
        "identity": "1530111@U22-SAC0130-ENG@",
        "requestId": "df4e6fb0-1eb1-47da-913c-7b010afa3098",
        "suggestContinueAsNew": false,
        "historySizeBytes": "1648"
      }
    },
    {
      "eventId": "13",
      "eventTime": "2023-08-24T01:12:23.623721221Z",
      "eventType": "WorkflowTaskCompleted",
      "version": "0",
      "taskId": "1048641",
      "workerMayIgnore": false,
      "workflowTaskCompletedEventAttributes": {
        "scheduledEventId": "11",
        "startedEventId": "12",
        "identity": "1530111@U22-SAC0130-ENG@",
        "binaryChecksum": "",
        "workerVersion": {
          "buildId": "0e18cf99ce54c91bcc93ba0861d7d3d9",
          "bundleId": "",
          "useVersioning": false
        },
        "sdkMetadata": {
          "coreUsedFlags": [],
          "langUsedFlags": []
        },
        "meteringMetadata": {
          "nonfirstLocalActivityExecutionAttempts": 0
        }
      }
    },
    {
      "eventId": "14",
      "eventTime": "2023-08-24T01:12:23.623742476Z",
      "eventType": "WorkflowExecutionCompleted",
      "version": "0",
      "taskId": "1048642",
      "workerMayIgnore": false,
      "workflowExecutionCompletedEventAttributes": {
        "result": {
          "payloads": [
            {
              "metadata": {
                "encoding": "anNvbi9wbGFpbg=="
              },
              "data": "IkhlbGxvIFdvcmxkISI="
            }
          ]
        },
        "workflowTaskCompletedEventId": "13",
        "newExecutionRunId": ""
      }
    }
  ]
}

History JSON does not have a workflow ID, so it won’t be accurate in a replayer. If you need accurate workflow ID during replay, instead of ReplayWorkflowHistoryFromJSONFile, you need to call ReplayWorkflowHistoryWithOptions with the ReplayWorkflowHistoryOptions.OriginalExecution set with the proper ID. Granted this call accepts a proto history object instead of a JSON file, so you’ll have to use something like jsonpb.UnmarshalString to turn JSON to History proto object.

@Chad_Retz

Any suggestion on how to reference the correct type when it’s an internal type for the workflow Execution? I tried to use the one defined in the common proto.

Use workflow.Execution alias instead.