temporalio/temporal · error

cannot serialize HSM task. unable to cast to expected type

Error message

cannot serialize HSM task. unable to cast to expected type

What it means

errSerializationCast is returned when serializing/deserializing HSM (hierarchical state machine) nexusoperation tasks: the code receives a persisted task object and cannot cast it to the expected Go type (one of ScheduleToCloseTimeoutTask, ScheduleToStartTimeoutTask, StartToCloseTimeoutTask, or completion tasks). It signals corrupt or unexpected persisted task data inside the nexusoperations component.

Source

Thrown at components/nexusoperations/tasks.go:29

	persistencespb "go.temporal.io/server/api/persistence/v1"
	"go.temporal.io/server/common/persistence/serialization"
	"go.temporal.io/server/service/history/consts"
	"go.temporal.io/server/service/history/hsm"
	"google.golang.org/protobuf/proto"
)

const (
	TaskTypeInvocation         = "nexusoperations.Invocation"
	TaskTypeBackoff            = "nexusoperations.Backoff"
	TaskTypeCancelation        = "nexusoperations.Cancelation"
	TaskTypeCancelationBackoff = "nexusoperations.CancelationBackoff"
	// NOTE: the name `Timeout` is used for backward compatibility with existing persisted tasks and predates the addition of more flexible timeout types.
	TaskTypeScheduleToCloseTimeout = "nexusoperations.Timeout"
	TaskTypeScheduleToStartTimeout = "nexusoperations.ScheduleToStartTimeout"
	TaskTypeStartToCloseTimeout    = "nexusoperations.StartToCloseTimeout"
)

var errSerializationCast = errors.New("cannot serialize HSM task. unable to cast to expected type")

type ScheduleToCloseTimeoutTask struct {
	deadline time.Time
}

var _ hsm.Task = ScheduleToCloseTimeoutTask{}

func (ScheduleToCloseTimeoutTask) Type() string {
	return TaskTypeScheduleToCloseTimeout
}

func (t ScheduleToCloseTimeoutTask) Deadline() time.Time {
	return t.deadline
}

func (ScheduleToCloseTimeoutTask) Destination() string {
	return ""
}

View on GitHub (pinned to bde624efd1)

Solutions

  1. Identify the workflow/task ID from logs and inspect the persisted HSM task record in the database for type mismatch
  2. Upgrade all server nodes to a consistent version so task type mappings agree
  3. If a specific task record is corrupt, let the task fail and rely on HSM failure handling/retries, or reset the workflow
  4. Report to Temporal if it reproduces on current versions - it indicates an internal serialization bug
Defensive patterns

Strategy: fallback

Prevention

When it happens

Trigger: Encoding/decoding an HSM task whose backing struct does not match the type registered for the task type string (e.g. 'nexusoperations.Timeout'); loading a persisted task created by a different server version whose type mapping changed.

Common situations: Server upgrades where nexusoperations task types were renamed or restructured (note the backward-compat name 'nexusoperations.Timeout'), corrupted persistence records, or manually edited workflow state.

Related errors


AI-assisted analysis of temporalio/temporal@bde624efd1 (2026-09-01). Data as JSON: /api/errors/e7c465429fd95b2d. Report an issue: GitHub.