vitessio/vitess · error
%s: %v
Error message
%s: %v
What it means
BuildBindVariables converts a map of Go values into query bind variables. It wraps any per-key failure from BuildBindVariable with the offending key name, so this '%s: %v' error carries the unsupported key plus the underlying cause.
Source
Thrown at go/sqltypes/bind_variables.go:71
return &querypb.Value{Type: v.Type(), Value: v.val}
}
// ProtoToValue converts a *querypb.Value to a Value.
func ProtoToValue(v *querypb.Value) Value {
return MakeTrusted(v.Type, v.Value)
}
// BuildBindVariables builds a map[string]*querypb.BindVariable from a map[string]any
func BuildBindVariables(in map[string]any) (map[string]*querypb.BindVariable, error) {
if len(in) == 0 {
return nil, nil
}
out := make(map[string]*querypb.BindVariable, len(in))
for k, v := range in {
bv, err := BuildBindVariable(v)
if err != nil {
return nil, fmt.Errorf("%s: %v", k, err)
}
out[k] = bv
}
return out, nil
}
// HexNumBindVariable converts bytes representing a hex number to a bind var.
func HexNumBindVariable(v []byte) *querypb.BindVariable {
return ValueBindVariable(NewHexNum(v))
}
// HexValBindVariable converts bytes representing a hex encoded string to a bind var.
func HexValBindVariable(v []byte) *querypb.BindVariable {
return ValueBindVariable(NewHexVal(v))
}
// BitNumBindVariable converts bytes representing a bit encoded string to a bind var.
func BitNumBindVariable(v []byte) *querypb.BindVariable {View on GitHub (pinned to 01a25a7d17)
Solutions
- Read the wrapped key and underlying message to find the offending bind variable
- Convert the value to a supported type (scalar, []byte, time.Time, or a typed list) before calling
- Pre-validate values with BuildBindVariable individually in a loop to isolate the bad key
Example fix
// before
vars := map[string]interface{}{"user": user} // user is a struct
// after
vars := map[string]interface{}{"user": user.ID} // pass a supported scalar Defensive patterns
Strategy: validation
Validate before calling
func validateBindValues(in map[string]interface{}) error {
for k, v := range in {
if _, err := sqltypes.BuildBindVariable(v); err != nil {
return fmt.Errorf("key %q: %v", k, err)
}
}
return nil
} Type guard
func isBindable(v interface{}) bool {
switch v.(type) {
case nil, string, []byte, int, int8, int16, int32, int64,
uint, uint8, uint16, uint32, uint64, float32, float64,
time.Time, *querypb.BindVariable:
return true
}
return false
} Try / catch
vars, err := sqltypes.BuildBindVariables(in)
if err != nil {
return vterrors.Errorf(vtrpcpb.Code_INVALID_ARGUMENT, "bad bind vars: %v", err)
} Prevention
- Only pass scalars, []byte, time.Time, or supported slices as bind values
- Never pass structs/maps as bind variables; serialize explicitly if needed
- Check for typed-nil pointers before binding
When it happens
Trigger: Calling BuildBindVariables (used by ExecOnTablet / ExecOnVTGate) with a map containing a value whose type BuildBindVariable cannot encode (unsupported type, nil, bad slice, etc.).
Common situations: Passing custom structs, maps, or nil pointers as bind values; a refactor changed a value's type; JSON-decoded data produced interface{} values of unexpected types.
Related errors
- type %T not supported as bind var: %v
- --batch-size only allowed when all queries are CREATE TABLE|
- UnescapeID err: invalid input identifier '%s'
- UnescapeID err: unexpected single backtick at position %d in
- UnescapeID err: no outer backticks found in the identifier '
AI-assisted analysis of vitessio/vitess@01a25a7d17 (2026-09-01).
Data as JSON: /api/errors/5c62c1c088a1fa50.
Report an issue: GitHub.