{"record":{"id":"8d475f378df24e11","repo":"temporalio/temporal","slug":"unknown-repication-task-type-v","errorCode":null,"errorMessage":"Unknown repication task type: %v","messagePattern":"Unknown repication task type: (.+?)","errorType":"panic","errorClass":null,"httpStatus":null,"severity":"critical","filePath":"service/history/replication/dlq_handler.go","lineNumber":293,"sourceCode":"\t\t\t\tWorkflowId:       task.WorkflowID,\n\t\t\t\tRunId:            task.RunID,\n\t\t\t\tTaskType:         enumsspb.TASK_TYPE_REPLICATION_SYNC_WORKFLOW_STATE,\n\t\t\t\tTaskId:           task.TaskID,\n\t\t\t\tVersion:          task.Version,\n\t\t\t\tFirstEventId:     0,\n\t\t\t\tNextEventId:      0,\n\t\t\t\tScheduledEventId: 0,\n\t\t\t})\n\t\tcase *tasks.SyncHSMTask:\n\t\t\ttaskInfo = append(taskInfo, &replicationspb.ReplicationTaskInfo{\n\t\t\t\tNamespaceId: task.NamespaceID,\n\t\t\t\tWorkflowId:  task.WorkflowID,\n\t\t\t\tRunId:       task.RunID,\n\t\t\t\tTaskType:    enumsspb.TASK_TYPE_REPLICATION_SYNC_HSM,\n\t\t\t\tTaskId:      task.TaskID,\n\t\t\t})\n\t\tdefault:\n\t\t\tpanic(fmt.Sprintf(\"Unknown repication task type: %v\", task))\n\t\t}\n\t}\n\n\tif len(taskInfo) == 0 {\n\t\treturn nil, nil, ackLevel, pageToken, nil\n\t}\n\n\tdlqResponse, err := remoteAdminClient.GetDLQReplicationMessages(\n\t\tctx,\n\t\t&adminservice.GetDLQReplicationMessagesRequest{\n\t\t\tTaskInfos: taskInfo,\n\t\t},\n\t)\n\tif err != nil {\n\t\treturn nil, nil, ackLevel, nil, err\n\t}\n\n\treturn dlqResponse.ReplicationTasks, taskInfo, ackLevel, pageToken, nil","sourceCodeStart":275,"sourceCodeEnd":311,"githubUrl":"https://github.com/temporalio/temporal/blob/bde624efd13fbd3843654058db6d9c716166318b/service/history/replication/dlq_handler.go#L275-L311","documentation":"readMessagesWithAckLevel converts tasks read from a replication DLQ into ReplicationTaskInfo protobufs; the switch handles SyncActivity, HistoryReplication, SyncWorkflowState and SyncHSM task types. Any other concrete task type in the DLQ is unsupported by this handler and panics. It guards against new task types being written to the DLQ without updating DLQ read logic.","triggerScenarios":"A DLQ containing a replication task type not covered by the switch — typically after a temporal-server upgrade introduces a new task type (e.g. a newer sync task) while the DLQ handler code was not updated, or DLQ data written by a newer/older cluster version being read by this version.","commonSituations":"Multi-cluster replication with version skew between clusters; applying schema/code updates to one cluster before the other; custom forks adding new replication task types.","solutions":["Upgrade both replication clusters to matching temporal-server versions so all DLQ task types are known","Add a switch case for the missing task type (map it to its enumsspb TASK_TYPE_* and required fields), then regenerate any affected code","Inspect the DLQ to identify the offending task type printed in the panic","As a workaround, drain/delete the incompatible DLQ messages only if replication state allows it"],"exampleFix":"// before\ndefault:\n  panic(fmt.Sprintf(\"Unknown repication task type: %v\", task))\n// after\ncase *tasks.NewReplicationTaskType:\n  taskInfo = append(taskInfo, &replicationspb.ReplicationTaskInfo{\n    NamespaceId: task.NamespaceID, WorkflowId: task.WorkflowID, RunId: task.RunID,\n    TaskType: enumsspb.TASK_TYPE_REPLICATION_NEW_TYPE, TaskId: task.TaskID,\n  })\ndefault:\n  panic(fmt.Sprintf(\"Unknown repication task type: %v\", task))","handlingStrategy":"type-guard","validationCode":"// Before reading DLQ messages, check task types are supported by this build:\nfor _, t := range resp.Tasks {\n  switch t.(type) {\n  case *tasks.SyncActivityTask, *tasks.HistoryReplicationTask,\n    *tasks.SyncWorkflowStateTask, *tasks.SyncHSMTask:\n  default:\n    return fmt.Errorf(\"unsupported DLQ task type %T; upgrade clusters to matching versions\", t)\n  }\n}","typeGuard":"func isSupportedDLQTask(t tasks.Task) bool {\n  switch t.(type) {\n  case *tasks.SyncActivityTask, *tasks.HistoryReplicationTask,\n    *tasks.SyncWorkflowStateTask, *tasks.SyncHSMTask:\n    return true\n  }\n  return false\n}","tryCatchPattern":"func safeGetMessages(h *replication.DLQHandler, req interface{}) (msgs interface{}, err error) {\n  defer func() { if r := recover(); r != nil { err = fmt.Errorf(\"dlq read panic: %v\", r) } }()\n  return h.GetMessages(req)\n}","preventionTips":["Keep replication clusters on matching temporal-server versions","Whenever adding a replication task type, update the DLQ handler's switch in the same change","Inspect DLQ contents after version upgrades before merging messages"],"tags":["go","replication","dlq","version-skew","unhandled-type"],"backgroundTag":"unknown-replication-task-type","analyzedSha":"bde624efd13fbd3843654058db6d9c716166318b","analyzedAt":"2026-09-01T07:18:39.080Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-08T10:18:20.063Z"}