vitessio/vitess · error

invalid type specified for MakeValue: %v

Error message

invalid type specified for MakeValue: %v

What it means

NewValue (MakeValue) builds a Value from bytes for a given type. Only numeric, datetime-ish, and quoted/hex/bit/null types are considered valid; anything else (e.g. Expression, Tuple types) is 'unsafe or invalid' for byte-backed values, so this error is returned with NULL.

Source

Thrown at go/sqltypes/value.go:120

		if _, err := fastparse.ParseUint64(hack.String(val), 10); err != nil {
			return NULL, err
		}
		return MakeTrusted(typ, val), nil
	case IsFloat(typ):
		if _, err := fastparse.ParseFloat64(hack.String(val)); err != nil {
			return NULL, err
		}
		return MakeTrusted(typ, val), nil
	case IsDecimal(typ):
		if _, err := decimal.NewFromMySQL(val); err != nil {
			return NULL, err
		}
		return MakeTrusted(typ, val), nil
	case IsQuoted(typ) || typ == Bit || typ == HexNum || typ == HexVal || typ == Null || typ == BitNum:
		return MakeTrusted(typ, val), nil
	}
	// All other types are unsafe or invalid.
	return NULL, fmt.Errorf("invalid type specified for MakeValue: %v", typ)
}

// MakeTrusted makes a new Value based on the type.
// This function should only be used if you know the value
// and type conform to the rules. Every place this function is
// called, a comment is needed that explains why it's justified.
// Exceptions: The current package and mysql package do not need
// comments. Other packages can also use the function to create
// VarBinary or VarChar values.
func MakeTrusted(typ querypb.Type, val []byte) Value {
	if typ == Null {
		return NULL
	}
	return Value{typ: uint16(typ), val: val}
}

// NewHexNum builds an Hex Value.
func NewHexNum(v []byte) Value {

View on GitHub (pinned to 01a25a7d17)

Solutions

  1. Only pass concrete data types (Int64, VarChar, Null, quoted types, etc.) to NewValue
  2. Handle Expression/Tuple types separately before calling NewValue
  3. Check sqltypes.IsQuoted/IsNumber guards before constructing

Example fix

// before
val, err := sqltypes.NewValue(query.Type_EXPRESSION, []byte("x + 1"))
// after
val := sqltypes.NewVarBinary("x + 1")
Defensive patterns

Strategy: validation

Validate before calling

func constructible(t querypb.Type) bool {
  return sqltypes.IsNumber(t) || sqltypes.IsQuoted(t) ||
    t == sqltypes.Bit || t == sqltypes.HexNum || t == sqltypes.HexVal ||
    t == sqltypes.Null || t == sqltypes.BitNum ||
    t == sqltypes.Timestamp || t == sqltypes.Date || t == sqltypes.Time || t == sqltypes.Datetime
}

Type guard

func canMakeValue(t querypb.Type) bool { return constructible(t) }

Try / catch

val, err := sqltypes.NewValue(typ, bytes)
if err != nil {
  return vterrors.Wrapf(err, "cannot build value for type %v", typ)
}

Prevention

When it happens

Trigger: Calling NewValue/Cast with a querypb.Type that cannot be constructed from raw bytes, such as querypb.Type_EXPRESSION or a tuple type, often via ValidateBindVariable or structToQueryValue on user-supplied data.

Common situations: Reflect-driven code copying a type from an AST expression node into a value constructor; bind-variable validation receiving a type set programmatically to an invalid value.

Related errors


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