temporalio/temporal · warning

callback with UNSPECIFIED state

Error message

callback with UNSPECIFIED state

What it means

errCallbackStateUnspecified is returned by buildCallbackInfoFromHSM when a callback's HSM state machine is in a state that maps to UNSPECIFIED in the API's CallbackInfo state enum. DescribeWorkflowExecution must report a concrete callback state; UNSPECIFIED indicates the state machine is in a state the API layer cannot represent (typically an internal/terminal bookkeeping state).

Source

Thrown at service/history/api/describeworkflow/api.go:46

	"go.temporal.io/server/common/log"
	"go.temporal.io/server/common/log/tag"
	"go.temporal.io/server/common/metrics"
	"go.temporal.io/server/common/namespace"
	"go.temporal.io/server/common/persistence/visibility/manager"
	"go.temporal.io/server/components/callbacks"
	"go.temporal.io/server/components/nexusoperations"
	"go.temporal.io/server/service/history/api"
	"go.temporal.io/server/service/history/circuitbreakerpool"
	"go.temporal.io/server/service/history/hsm"
	historyi "go.temporal.io/server/service/history/interfaces"
	"go.temporal.io/server/service/history/tasks"
	"go.temporal.io/server/service/history/workflow"
	"google.golang.org/protobuf/types/known/durationpb"
	"google.golang.org/protobuf/types/known/timestamppb"
)

var (
	errCallbackStateUnspecified       = errors.New("callback with UNSPECIFIED state")
	errNexusOperationStateUnspecified = errors.New("Nexus operation with UNSPECIFIED state")
)

func clonePayloadMap(source map[string]*commonpb.Payload) map[string]*commonpb.Payload {
	target := make(map[string]*commonpb.Payload, len(source))
	for k, v := range source {
		metadata := make(map[string][]byte, len(v.GetMetadata()))
		maps.Copy(metadata, v.GetMetadata())
		target[k] = &commonpb.Payload{
			Metadata: metadata,
			Data:     v.GetData(),
		}
	}
	return target
}

func Invoke(
	ctx context.Context,

View on GitHub (pinned to bde624efd1)

Solutions

  1. Retry the describe after the callback state machine settles into a concrete state
  2. Ensure the server version maps all current HSM callback states to defined CallbackState values (upgrade if needed)
  3. If persistent on a current version, capture the workflow ID and HSM state and report to Temporal - it indicates a missing state mapping
Defensive patterns

Strategy: retry

Try / catch

info, err := describeWorkflowExecution(ctx, req)
if errors.Is(err, errCallbackStateUnspecified) { time.Sleep(backoff); info, err = describeWorkflowExecution(ctx, req) }

Prevention

When it happens

Trigger: DescribeWorkflowExecution on a workflow with a callback (e.g. a Nexus operation callback) whose HSM state does not map to a defined enumspb.CallbackState - e.g. state still initializing or in an internal-only state.

Common situations: Describing a workflow while a callback is being created/cleaned up, server version skew where new HSM states exist but the enum mapping is incomplete, or API clients on older SDKs seeing newer state mappings.

Related errors


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