milvus-io/milvus · critical
unexpected values type(%T) of fieldType %v
Error message
unexpected values type(%T) of fieldType %v
What it means
A Go panic in the Milvus SDK's column conversion helper (values2Scalars). After a type-switch over field types, if the generic []T slice stored in the interface cannot be asserted to the concrete slice type the field requires (e.g. the values are []int32 but the field is declared Int64), ok stays false and the SDK panics rather than returning an error. It indicates the Go type of the inserted column data does not match the schema field type.
Source
Thrown at client/column/conversion.go:102
var doubles []float64
doubles, ok = any(values).([]float64)
scalarField.Data = &schemapb.ScalarField_DoubleData{
DoubleData: &schemapb.DoubleArray{
Data: doubles,
},
}
case entity.FieldTypeVarChar, entity.FieldTypeString:
var strings []string
strings, ok = any(values).([]string)
scalarField.Data = &schemapb.ScalarField_StringData{
StringData: &schemapb.StringArray{
Data: strings,
},
}
}
if !ok {
panic(fmt.Sprintf("unexpected values type(%T) of fieldType %v", values, elementType))
}
return scalarField
}
func values2FieldData[T any](values []T, fieldType entity.FieldType, dim int) *schemapb.FieldData {
fd := &schemapb.FieldData{}
switch fieldType {
// scalars
case entity.FieldTypeBool,
entity.FieldTypeFloat,
entity.FieldTypeDouble,
entity.FieldTypeInt8,
entity.FieldTypeInt16,
entity.FieldTypeInt32,
entity.FieldTypeInt64,
entity.FieldTypeVarChar,
entity.FieldTypeText,
entity.FieldTypeString,View on GitHub (pinned to b43a76673a)
Solutions
- Match the Go slice element type exactly to the schema field type per the SDK table: BoolVector->[]bool, Int8/16/32->[]int8/16/32, Int64->[]int64, Float->[]float32, Double->[]float64, VarChar->[]string.
- Convert before insert: cast []int to []int64, []float64 to []float32, fmt.Sprintf numbers for VarChar.
- Check the panic message's %T verb - it prints the actual slice type you passed, which tells you exactly what to convert from.
- If types genuinely vary at runtime, switch to building typed columns explicitly (column.NewColumnInt64 etc.) instead of the generic values path.
Example fix
// before
fieldData := values2Scalars(int32Values, entity.FieldTypeInt64) // panics: %T = []int32
// after
int64Values := make([]int64, len(int32Values))
for i, v := range int32Values {
int64Values[i] = int64(v)
}
fieldData := values2Scalars(int64Values, entity.FieldTypeInt64) Defensive patterns
Strategy: type-guard
Type guard
func scalarSliceForType(fieldType entity.FieldType, values any) error {
switch fieldType {
case entity.FieldTypeBool:
if _, ok := values.([]bool); !ok { return fmt.Errorf("want []bool, got %T", values) }
case entity.FieldTypeInt8:
if _, ok := values.([]int8); !ok { return fmt.Errorf("want []int8, got %T", values) }
case entity.FieldTypeInt16:
if _, ok := values.([]int16); !ok { return fmt.Errorf("want []int16, got %T", values) }
case entity.FieldTypeInt32:
if _, ok := values.([]int32); !ok { return fmt.Errorf("want []int32, got %T", values) }
case entity.FieldTypeInt64:
if _, ok := values.([]int64); !ok { return fmt.Errorf("want []int64, got %T", values) }
case entity.FieldTypeFloat:
if _, ok := values.([]float32); !ok { return fmt.Errorf("want []float32, got %T", values) }
case entity.FieldTypeDouble:
if _, ok := values.([]float64); !ok { return fmt.Errorf("want []float64, got %T", values) }
case entity.FieldTypeVarChar, entity.FieldTypeString:
if _, ok := values.([]string); !ok { return fmt.Errorf("want []string, got %T", values) }
}
return nil
} Try / catch
defer func() {
if r := recover(); r != nil {
err = fmt.Errorf("column conversion panic (likely Go slice type does not match schema field type): %v", r)
}
}() Prevention
- Keep Go slice element types exactly aligned with the schema: Float is float32, Double is float64, Int64 is int64.
- Convert decoded data ([]float64 from JSON -> []float32, []int -> []int64) before insert.
- Wrap the insert/conversion call in a recover at the batch boundary so type bugs become errors, not crashes.
- Read the panic message - the %T verb names the concrete type you actually passed.
When it happens
Trigger: Building a column via column.NewXxx or the generic conversion path with a Go slice type that disagrees with entity.FieldType: []int32 with FieldTypeInt64, []float32 with FieldTypeDouble, []int with FieldTypeInt32, or any non-string slice for VarChar/String fields (the String case leaves ok false for anything else).
Common situations: Schema migrated (Int64 -> Int32) while insertion code kept the old Go type; JSON decoding numbers as []float64 and inserting directly; generics path where values arrive as []any or []interface{}.
Related errors
- index out of range
- struct array %q sub-field %q length %d mismatches first sub-
- MetaStoreType %s not supported
AI-assisted analysis of milvus-io/milvus@b43a76673a (2026-08-15).
Data as JSON: /api/errors/645f6e43834dadbc.
Report an issue: GitHub.