{"record":{"id":"881022a65f72def5","repo":"temporalio/temporal","slug":"unknown-transfer-task","errorCode":null,"errorMessage":"unknown transfer task","messagePattern":"unknown transfer task","errorType":"panic","errorClass":null,"httpStatus":null,"severity":"error","filePath":"service/history/tasks/utils.go","lineNumber":84,"sourceCode":"\t\teventID = task.ScheduledEventID\n\tcase *CloseExecutionTask:\n\t\teventID = common.FirstEventID\n\tcase *DeleteExecutionTask:\n\t\treturn getChasmTaskEventID()\n\tcase *CancelExecutionTask:\n\t\teventID = task.InitiatedEventID\n\tcase *SignalExecutionTask:\n\t\teventID = task.InitiatedEventID\n\tcase *StartChildExecutionTask:\n\t\teventID = task.InitiatedEventID\n\tcase *ResetWorkflowTask:\n\t\teventID = common.FirstEventID\n\tcase *ChasmTask:\n\t\treturn getChasmTaskEventID()\n\tcase *FakeTask:\n\t\t// no-op\n\tdefault:\n\t\tpanic(serviceerror.NewInternal(\"unknown transfer task\"))\n\t}\n\treturn eventID, true\n}\n\nfunc GetTimerTaskEventID(\n\ttimerTask Task,\n) (int64, bool) {\n\teventID := int64(0)\n\n\tswitch task := timerTask.(type) {\n\tcase *UserTimerTask:\n\t\teventID = task.EventID\n\tcase *ActivityTimeoutTask:\n\t\teventID = task.EventID\n\tcase *WorkflowTaskTimeoutTask:\n\t\teventID = task.EventID\n\tcase *WorkflowBackoffTimerTask:\n\t\teventID = common.FirstEventID","sourceCodeStart":66,"sourceCodeEnd":102,"githubUrl":"https://github.com/temporalio/temporal/blob/bde624efd13fbd3843654058db6d9c716166318b/service/history/tasks/utils.go#L66-L102","documentation":"GetTransferTaskEventID maps a concrete transfer Task implementation to the workflow event ID that spawned it. The type switch covers all known transfer task types; when a new transfer task implementation is added to the tasks package but not added to this switch, the default branch panics with an internal service error. Tags() relies on this function to attach event-ID tags to task metrics/logs.","triggerScenarios":"Passing an unhandled transfer Task concrete type (anything not covered by the switch, e.g. a new *SomeNewTask struct) into GetTransferTaskEventID — typically via Tags() on a task whose type was added upstream but not handled in this fork/version.","commonSituations":"Version skew: a newer Temporal release introduces a new transfer task type while an older node processes it; custom forks adding task types without updating utils.go; misdeserialized tasks yielding an unexpected concrete type.","solutions":["Add a case for the unhandled task type in GetTransferTaskEventID returning the correct event ID.","Align service versions so all history nodes know the same set of transfer task types.","Check whether the task was corrupted in persistence (wrong type field) and repair or drop the row.","Add a compile-time exhaustiveness aid (e.g. a unit test enumerating all transfer task types) to catch future additions."],"exampleFix":"// before\ncase *ChasmTask:\n    return getChasmTaskEventID()\ndefault:\n    panic(serviceerror.NewInternal(\"unknown transfer task\"))\n\n// after\ncase *ChasmTask:\n    return getChasmTaskEventID()\ncase *NewTransferTask:\n    eventID = task.GetEventID()\n    return eventID, true\ndefault:\n    panic(serviceerror.NewInternal(\"unknown transfer task\"))","handlingStrategy":"type-guard","validationCode":"switch t.(type) {\ncase *tasks.TransferWorkflowTask, *tasks.TransferActivityTask, *tasks.TransferChasmTask:\n    // safe to call\ndefault:\n    return fmt.Errorf(\"transfer task type %T unsupported\", t)\n}","typeGuard":"func isKnownTransferTask(t tasks.Task) bool {\n    switch t.(type) {\n    case *tasks.TransferWorkflowTask, *tasks.TransferActivityTask,\n        *tasks.TransferWorkflowTaskTimer, *tasks.TransferActivityTimeoutTask,\n        *tasks.TransferCloseTask, *tasks.TransferCancelTask, *tasks.TransferSignalTask,\n        *tasks.TransferDeleteExecutionTask, *tasks.TransferChasmTask, *tasks.FakeTask:\n        return true\n    }\n    return false\n}","tryCatchPattern":null,"preventionTips":["Update GetTransferTaskEventID whenever a new transfer task struct is added","Keep all history nodes on the same release version","Add an exhaustiveness unit test enumerating all transfer task types","Validate task type fields read from persistence"],"tags":["transfer-task","panic","type-switch","history-service","version-skew"],"backgroundTag":"unknown-task-type","analyzedSha":"bde624efd13fbd3843654058db6d9c716166318b","analyzedAt":"2026-09-01T07:18:39.080Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-08T10:18:20.063Z"}