temporalio/temporal · error

serializer error

Error message

serializer error

What it means

errSerializer is the base sentinel error for the nexus payloadSerializer in common/nexus/payload_serializer.go. Serialize and Deserialize wrap it (with fmt.Errorf "%w: ...") when the value being (de)serialized is not the expected *commonpb.Payload type or the underlying persistence serialization fails. Because it is wrapped, callers can match it with errors.Is.

Solutions

  1. Check errors.Is(err, nexus.ErrSerializer) and read the wrapped detail for the actual cause
  2. Pass **commonpb.Payload (pointer-to-pointer) as the value for Deserialize
  3. For custom types, implement nexus.Serializer instead of relying on the default payload serializer
  4. Inspect the payload data for corruption if the wrapped cause is a persistence serialization failure

Example fix

// before
var s string
cerr := serializer.Deserialize(content, &s)
// after
var payload *commonpb.Payload
if err := serializer.Deserialize(content, &payload); err != nil {
    if errors.Is(err, nexus.ErrSerializer) { /* handle type/serialization mismatch */ }
}
Defensive patterns

Strategy: type-guard

Validate before calling

func asPayload(v any) (*commonpb.Payload, bool) {
    p, ok := v.(*commonpb.Payload)
    return p, ok && p != nil
}

Type guard

payloadRef, ok := v.(**commonpb.Payload)
if !ok { return fmt.Errorf("%w: cannot deserialize into %v", nexus.ErrSerializer, v) }

Try / catch

if err := serializer.Deserialize(content, &payload); err != nil {
    if errors.Is(err, nexus.ErrSerializer) {
        // inspect wrapped cause: wrong target type vs corrupted data
    }
}

Prevention

When it happens

Trigger: Calling Deserialize with a target that is not **commonpb.Payload; calling Serialize with an unsupported value; or an underlying serialization failure while converting between nexus Content and Payload.

Common situations: Passing arbitrary Go values (strings, structs) to the nexus serializer instead of Payload pointers; using a custom serializer with mismatched expectations; corrupted payloads from persistence failing to deserialize.

Related errors


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

Appendix: source

Thrown at common/nexus/payload_serializer.go:17

package nexus

import (
	"errors"
	"fmt"
	"maps"
	"mime"

	"github.com/nexus-rpc/sdk-go/nexus"
	commonpb "go.temporal.io/api/common/v1"
	enumspb "go.temporal.io/api/enums/v1"
	"go.temporal.io/server/common/persistence/serialization"
)

type payloadSerializer struct{}

var errSerializer = errors.New("serializer error")

// Deserialize implements nexus.Serializer.
func (payloadSerializer) Deserialize(content *nexus.Content, v any) error {
	payloadRef, ok := v.(**commonpb.Payload)
	if !ok {
		return fmt.Errorf("%w: cannot deserialize into %v", errSerializer, v)
	}

	payload := &commonpb.Payload{}
	*payloadRef = payload
	payload.Metadata = make(map[string][]byte)
	payload.Data = content.Data

	h := maps.Clone(content.Header)
	// We assume that encoding is handled by the transport layer and the content is decoded.
	delete(h, "encoding")
	// Length can safely be ignored.
	delete(h, "length")

View on GitHub (pinned to bde624efd1)