vitessio/vitess · error

enum or set column %s does not have valid string values: %q;

Error message

enum or set column %s does not have valid string values: %q; the column's type definition is unavailable -- this usually means the column was dropped, and decoding historical rows for a dropped ENUM/SET column requires --track-schema-versions with a schema version retained from while the column still existed

What it means

To decode ENUM/SET values, vstreamer needs the string value list from the column's ColumnType (e.g. enum('a','b')). If the parentheses delimiting the value list are missing — meaning the type definition is unavailable, typically because the column was dropped — the historical row cannot be decoded and this actionable error is returned pointing to --track-schema-versions.

Source

Thrown at go/vt/vttablet/tabletserver/vstreamer/vstreamer.go:1408

// addEnumAndSetMappingstoPlan sets up any necessary ENUM and SET integer to string mappings.
func addEnumAndSetMappingstoPlan(env *vtenv.Environment, plan *Plan, cols []*querypb.Field, metadata []uint16) error {
	plan.EnumSetValuesMap = make(map[int]map[int]string)
	for i, col := range cols {
		// If the column is a CHAR based type with a binary collation (e.g. utf8mb4_bin) then
		// the actual column type is included in the second byte of the event metadata while
		// the event's type for the field is BINARY. This is true for ENUM and SET types.
		var mysqlType uint16
		if sqltypes.IsQuoted(col.Type) {
			mysqlType = metadata[i] >> 8
		}
		if col.Type == querypb.Type_ENUM || mysqlType == mysqlbinlog.TypeEnum ||
			col.Type == querypb.Type_SET || mysqlType == mysqlbinlog.TypeSet {
			// Strip the enum() / set() parts out.
			begin := strings.Index(col.ColumnType, "(")
			end := strings.LastIndex(col.ColumnType, ")")
			if begin == -1 || end == -1 {
				return fmt.Errorf("enum or set column %s does not have valid string values: %q; "+
					"the column's type definition is unavailable -- this usually means the column "+
					"was dropped, and decoding historical rows for a dropped ENUM/SET column "+
					"requires --track-schema-versions with a schema version retained from while "+
					"the column still existed", col.Name, col.ColumnType)
			}
			var err error
			plan.EnumSetValuesMap[i], err = vtschema.ParseEnumOrSetTokensMap(env, col.ColumnType[begin+1:end])
			if err != nil {
				return err
			}
		}
	}
	return nil
}

// buildEnumStringValue takes the integer value of an ENUM column and returns the string value.
func buildEnumStringValue(env *vtenv.Environment, plan *streamerPlan, colNum int, value sqltypes.Value) (sqltypes.Value, error) {
	if value.IsNull() { // No work is needed

View on GitHub (pinned to 01a25a7d17)

Solutions

  1. Enable --track-schema-versions and retain the schema version captured while the ENUM/SET column still existed
  2. Restore the column (re-add it with the same definition) if the historical rows must be decoded
  3. Rebuild the table/re-copy data so old rows no longer need the dropped column's definition
  4. Skip or reposition the stream past events written before the column was dropped

Example fix

// before (vttablet flags)
vttablet ... # no schema version tracking
// after
vttablet ... --track-schema-versions
Defensive patterns

Strategy: validation

Validate before calling

// Confirm the column's type definition is retained:
// SELECT column_type FROM information_schema.columns
//  WHERE table_name='<t>' AND column_name='<c>'; -- must contain enum(...)/set(...)
// Enable --track-schema-versions on vttablet for historical decode.

Try / catch

if strings.Contains(err.Error(), "does not have valid string values") {
    // enable/retain --track-schema-versions with the pre-DROP schema version, or skip past the dropped-column rows
}

Prevention

When it happens

Trigger: addEnumAndSetMappingstoPlan finds col.Type is ENUM or SET (or the binlog type is TypeEnum/TypeSet) but strings.Index/LastIndex of '(' and ')' in col.ColumnType return -1, so no value list can be extracted.

Common situations: Replaying old binlog rows for a table whose ENUM/SET column was since dropped; minimal schema (no full column types) cached for the table; missing --track-schema-versions history for the pre-DROP definition.

Related errors


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