temporalio/temporal · error
unexpected result from transitionhistory.Compare
Error message
unexpected result from transitionhistory.Compare
What it means
This panic guards the exhaustive switch over transitionhistory.Compare results when comparing an execution state against a submitted ref versioned transition. Compare should only yield -1, 0, or 1 (the handled cases 0 and 1 plus the default/0 path); any other result means the comparison primitive returned something unexpected, indicating a bug in transition history data or the Compare implementation. It is reached via the public ExecutionStateChanged path.
Source
Thrown at chasm/transition_history.go:34
currentRef, err := ctx.structuredRef(c)
if err != nil {
return false, err
}
if ref.ExecutionKey != currentRef.ExecutionKey {
return false, ErrInvalidComponentRef
}
switch transitionhistory.Compare(ref.executionLastUpdateVT, currentRef.executionLastUpdateVT) {
case -1:
// Execution state has advanced beyond submitted ref
return true, nil
case 0:
// Execution state has not advanced beyond submitted ref
return false, nil
case 1:
// Execution state is behind submitted ref
return false, consts.ErrStaleState
}
panic("unexpected result from transitionhistory.Compare") //nolint:forbidigo
}
View on GitHub (pinned to bde624efd1)
Solutions
- Inspect the versioned transitions being compared (task/ref metadata) for malformed or zero values in persistence
- Verify transitionhistory.Compare normalizes its result to -1/0/1; fix or update it if changed
- Update the switch in this function if a new legitimate comparison result was introduced
- Report as a bug if internal data is well-formed — this is an internal invariant violation
Defensive patterns
Strategy: try-catch
Try / catch
defer func() {
if r := recover(); r != nil {
if s, ok := r.(string); ok && strings.Contains(s, "unexpected result from transitionhistory.Compare") {
// log execution + versioned transitions, report bug
return
}
panic(r)
}
}() Prevention
- Keep versioned transition metadata well-formed in persistence
- Don't modify transitionhistory.Compare to return unclamped values without auditing all switches
- Report occurrences as internal bugs with full state
When it happens
Trigger: ExecutionStateChanged (or code calling it) compares a versioned transition against the submitted ref and the switch on transitionhistory.Compare(...) falls through all expected cases — i.e. Compare returns a value outside {-1,0,1} (Go's switch here relies on Compare returning a normalized -1/0/1).
Common situations: Corrupted or malformed VersionedTransition metadata in persistence (e.g. unset/zero-valued fields interacting oddly); a change to transitionhistory.Compare that no longer clamps to -1/0/1; a new case value introduced by an upgrade without updating this switch.
Related errors
- component is not registered to a library
- task is not registered to a library
- failed to encode chasm path on clean tree: %v
- Failed to get HSM operation log: %v
- registrable component validation error: CHASM search attribu
AI-assisted analysis of temporalio/temporal@bde624efd1 (2026-09-01).
Data as JSON: /api/errors/0f5ee2ddc0249c9e.
Report an issue: GitHub.