{"record":{"id":"0d15af2cf42a3030","repo":"hyperledger/fabric","slug":"unsupported-slice-type-v-for-field-s","errorCode":null,"errorMessage":"unsupported slice type %v for field %s","messagePattern":"unsupported slice type (.+?) for field (.+?)","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"core/chaincode/lifecycle/serializer.go","lineNumber":98,"sourceCode":"\t\treturn reflect.Value{}, nil, errors.Errorf(\"must be pointer to struct, but got non-pointer %v\", value.Kind())\n\t}\n\n\tvalue = value.Elem()\n\tif value.Kind() != reflect.Struct {\n\t\treturn reflect.Value{}, nil, errors.Errorf(\"must be pointers to struct, but got pointer to %v\", value.Kind())\n\t}\n\n\tallFields := make([]string, value.NumField())\n\tfor i := 0; i < value.NumField(); i++ {\n\t\tfieldName := value.Type().Field(i).Name\n\t\tfieldValue := value.Field(i)\n\t\tallFields[i] = fieldName\n\t\tswitch fieldValue.Kind() {\n\t\tcase reflect.String:\n\t\tcase reflect.Int64:\n\t\tcase reflect.Slice:\n\t\t\tif fieldValue.Type().Elem().Kind() != reflect.Uint8 {\n\t\t\t\treturn reflect.Value{}, nil, errors.Errorf(\"unsupported slice type %v for field %s\", fieldValue.Type().Elem().Kind(), fieldName)\n\t\t\t}\n\t\tcase reflect.Pointer:\n\t\t\tif !fieldValue.Type().Implements(ProtoMessageType) {\n\t\t\t\treturn reflect.Value{}, nil, errors.Errorf(\"unsupported pointer type %v for field %s (must be proto)\", fieldValue.Type().Elem(), fieldName)\n\t\t\t}\n\t\tdefault:\n\t\t\treturn reflect.Value{}, nil, errors.Errorf(\"unsupported structure field kind %v for serialization for field %s\", fieldValue.Kind(), fieldName)\n\t\t}\n\t}\n\treturn value, allFields, nil\n}\n\n// Serialize takes a pointer to a struct, and writes each of its fields as keys\n// into a namespace.  It also writes the struct metadata (if it needs updating)\n// and,  deletes any keys in the namespace which are not found in the struct.\n// Note: If a key already exists for the field, and the value is unchanged, then\n// the key is _not_ written to.\nfunc (s *Serializer) Serialize(namespace, name string, structure any, state ReadWritableState) error {","sourceCodeStart":80,"sourceCodeEnd":116,"githubUrl":"https://github.com/hyperledger/fabric/blob/2736b63f8fd5932511d56fe68b7039d15977f7f6/core/chaincode/lifecycle/serializer.go#L80-L116","documentation":"The serializer supports only string, int64, []byte (uint8 slice), and proto pointer fields. If a struct field is a slice whose element type is not uint8 (e.g. []string, []int64), SerializableChecks rejects it with this error naming the element kind and field name.","triggerScenarios":"Defining a lifecycle state struct with fields like []string, []uint64, [][]byte and calling Serialize/IsSerialized/Deserialize on it.","commonSituations":"Adding a list of peer addresses/endorsements ([]string) to a chaincode metadata struct; modeling repeated proto fields as Go slices in state structs.","solutions":["Change the field to []byte and encode lists with json.Marshal or proto.Marshal before serializing","Use a proto pointer field holding a repeated-field message instead of a Go slice","Re-check the struct against the supported kinds: string, int64, []byte, proto pointer"],"exampleFix":"// before\ntype Def struct { Peers []string }\n// after\ntype Def struct { Peers []byte } // json.Marshal([]string{...}) into bytes","handlingStrategy":"validation","validationCode":"func noNonByteSlices(v any) error {\n  rv := reflect.ValueOf(v).Elem()\n  t := rv.Type()\n  for i := 0; i < t.NumField(); i++ {\n    f := t.Field(i).Type\n    if f.Kind() == reflect.Slice && f.Elem().Kind() != reflect.Uint8 {\n      return fmt.Errorf(\"field %s: only []byte slices supported\", t.Field(i).Name)\n    }\n  }\n  return nil\n}","typeGuard":"func isByteSlice(f reflect.Type) bool { return f.Kind() == reflect.Slice && f.Elem().Kind() == reflect.Uint8 }","tryCatchPattern":"_, _, err := s.SerializableChecks(input)\nif err != nil && strings.Contains(err.Error(), \"unsupported slice type\") {\n  // encode the slice as []byte and retry\n}","preventionTips":["Keep state structs limited to string/int64/[]byte/proto pointer fields","Encode lists with json.Marshal or proto messages before persisting","Lint/validate new struct fields against the supported kinds"],"tags":["fabric","serialization","unsupported-type","struct-field"],"backgroundTag":"unsupported-struct-field-type","analyzedSha":"2736b63f8fd5932511d56fe68b7039d15977f7f6","analyzedAt":"2026-09-04T08:52:36.465Z","contentChangedAt":"2026-09-04T08:52:36.465Z","schemaVersion":2},"datasetVersion":"2026-09-08T10:18:20.063Z"}