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
- Retry the describe after the callback state machine settles into a concrete state
- Ensure the server version maps all current HSM callback states to defined CallbackState values (upgrade if needed)
- 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
- Avoid describing workflows immediately while callbacks are being set up or cleaned up
- Keep server and API versions aligned so callback HSM states map to defined enum values
- Monitor for persistent occurrences and report as a missing state-mapping bug
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
- cannot serialize HSM task. unable to cast to expected type
- completion token has no operation state machine reference
- internal error, reference-id: %v
- ErrStaleReference
- %w: %w
AI-assisted analysis of temporalio/temporal@bde624efd1 (2026-09-01).
Data as JSON: /api/errors/7e96d2272d9fe1c9.
Report an issue: GitHub.