vitessio/vitess · critical

all vterrors states are not mapped to mysql errors

Error message

all vterrors states are not mapped to mysql errors

What it means

The sqlerror package maintains a map from every vtrpcpb.Code state to a MySQL SQLSTATE string. An init()-time panic fires if the number of mapped states doesn't equal vterrors.NumOfStates, i.e. a new vterrors state code was added without a corresponding MySQL state mapping. This is a build-time/program-start invariant check, not a runtime data error.

Source

Thrown at go/mysql/sqlerror/sql_error.go:375

}

// ConvertStateToMySQLErrorCode returns MySQL error code for the given vterrors.State
// If the state is == 0, an empty string is returned
func ConvertStateToMySQLErrorCode(state vterrors.State) string {
	s := getStateToMySQLState(state)
	return s.num.ToString()
}

// ConvertStateToMySQLState returns MySQL state for the given vterrors.State
// If the state is == 0, an empty string is returned
func ConvertStateToMySQLState(state vterrors.State) string {
	s := getStateToMySQLState(state)
	return s.state
}

func init() {
	if len(stateToMysqlCode) != int(vterrors.NumOfStates) {
		panic("all vterrors states are not mapped to mysql errors")
	}
}

func convertToMysqlError(err error) error {
	errState := vterrors.ErrState(err)
	if errState == vterrors.Undefined {
		return err
	}
	mysqlCode, ok := stateToMysqlCode[errState]
	if !ok {
		return err
	}
	return NewSQLError(mysqlCode.num, mysqlCode.state, err.Error())
}

var isGRPCOverflowRE = regexp.MustCompile(`.*?grpc: (received|trying to send) message larger than max \(\d+ vs. \d+\)`)

func demuxResourceExhaustedErrors(msg string) ErrorCode {

View on GitHub (pinned to 01a25a7d17)

Solutions

  1. Add the missing state to stateToMysqlCode in go/mysql/sqlerror/sql_error.go with an appropriate MySQL SQLSTATE.
  2. Run go mod tidy / align all vitess module versions so vterrors and sqlerror come from the same commit.
  3. Rebuild from a clean checkout to rule out stale builds mixing old and new packages.

Example fix

// before (new state added, map unchanged)
var stateToMysqlCode = map[vtrpcpb.Code]mysqlState{ ... } // missing new state
// after
var stateToMysqlCode = map[vtrpcpb.Code]mysqlState{
    ...
    vtrpcpb.Code_NEW_STATE: {state: "HY000", code: 1105}, // add mapping
}
Defensive patterns

Strategy: validation

Validate before calling

// startup self-check before shipping:
if len(stateToMysqlCode) != int(vterrors.NumOfStates) {
    return fmt.Errorf("missing mysql state mapping for a vterrors state")
}

Try / catch

// init panic cannot be recovered at use-site; add a unit test:
func TestAllStatesMapped(t *testing.T) {
    require.Equal(t, int(vterrors.NumOfStates), len(stateToMysqlCode))
}

Prevention

When it happens

Trigger: Starting any binary that imports go/mysql/sqlerror after adding a new vtrpcpb.Code state to the vterrors package without adding it to stateToMysqlCode; upgrading vitess libs where one module version is out of sync.

Common situations: Developers adding a new gRPC status code; mismatched vendored module versions where vterrors was bumped but sqlerror's map wasn't (partial dependency upgrade).

Related errors


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