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

  1. Inspect the versioned transitions being compared (task/ref metadata) for malformed or zero values in persistence
  2. Verify transitionhistory.Compare normalizes its result to -1/0/1; fix or update it if changed
  3. Update the switch in this function if a new legitimate comparison result was introduced
  4. 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

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


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