vitessio/vitess · error

BUG: invalid state: %v

Error message

BUG: invalid state: %v

What it means

recalculateRate's state switch handles all known throttler tester states (increase rate, decrease and guess, emergency, etc.). If r.TestedState holds any value outside that set, the default branch panics, since the state machine has no defined transition. This indicates a corrupted or uninitialized state enum.

Source

Thrown at go/vt/throttler/max_replication_lag_module.go:374

	if !m.isReplicaUnderTest(&r, now, r.TestedState, lagRecordNow) {
		goto logResult
	}

	// Process the lag record and adjust the rate.
	if m.replicaUnderTest != nil {
		// We're checking the same replica again. The old value is no longer needed.
		m.replicaUnderTest = nil
	}
	switch r.TestedState {
	case stateIncreaseRate:
		m.increaseRate(&r, now, lagRecordNow)
	case stateDecreaseAndGuessRate:
		m.decreaseAndGuessRate(&r, now, lagRecordNow)
	case stateEmergency:
		m.emergency(&r, now, lagRecordNow)
	default:
		panic(fmt.Sprintf("BUG: invalid state: %v", r.TestedState))
	}

logResult:
	r.HighestGood = m.memory.highestGood()
	r.LowestBad = m.memory.lowestBad()

	if clear {
		r.Reason += clearReason
	}

	m.results.add(r)
}

// clearReplicaUnderTest returns true if the current "replica under test" should
// be cleared e.g. because the new lag record is more severe or we did not hear
// back from the replica under test for a while.
func (m *MaxReplicationLagModule) clearReplicaUnderTest(now time.Time, testedState state, lagRecordNow replicationLagRecord) (bool, string) {
	if m.replicaUnderTest == nil {

View on GitHub (pinned to 01a25a7d17)

Solutions

  1. Initialize TestedState to a valid state (the constructor's default state) before invoking recalculateRate.
  2. Audit any code that writes r.TestedState for out-of-range assignments.
  3. If state is persisted/loaded across versions, validate it against the known enum set before use.

Example fix

// before
r := &Tester{}
m.recalculateRate(lagRecord) // TestedState zero => panic
// after
r := newTesterForTest(... ) // sets TestedState to a valid initial state
m.recalculateRate(lagRecord)
Defensive patterns

Strategy: validation

Validate before calling

func validState(s testerState) bool {
  switch s {
  case stateIncreaseRate, stateDecreaseAndGuessRate, stateEmergency /* + others */ :
    return true
  }
  return false
}
// require validState(r.TestedState) before recalculateRate

Prevention

When it happens

Trigger: Entering recalculateRate with a Tester whose TestedState field was never initialized or was set to an out-of-range numeric value — typically via an uninitialized struct, a bad cast, or deserialization of a corrupted state.

Common situations: Unit tests constructing a Tester without setting TestedState; loading persisted throttler state written by a different code version with a shifted enum; manual mutation of Tester fields.

Related errors


AI-assisted analysis of vitessio/vitess@01a25a7d17 (2026-09-01). Data as JSON: /api/errors/6491223c1aabc5be. Report an issue: GitHub.