{"record":{"id":"07347debf2d19aeb","repo":"hyperledger/fabric","slug":"unsupported-structure-field-kind-v-for-serializat","errorCode":null,"errorMessage":"unsupported structure field kind %v for serialization for field %s","messagePattern":"unsupported structure field kind (.+?) for serialization for field (.+?)","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"core/chaincode/lifecycle/serializer.go","lineNumber":105,"sourceCode":"\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 {\n\tvalue, allFields, err := s.SerializableChecks(structure)\n\tif err != nil {\n\t\treturn errors.WithMessagef(err, \"structure for namespace %s/%s is not serializable\", namespace, name)\n\t}\n\n\tmetadata, ok, err := s.DeserializeMetadata(namespace, name, state)\n\tif err != nil {","sourceCodeStart":87,"sourceCodeEnd":123,"githubUrl":"https://github.com/hyperledger/fabric/blob/2736b63f8fd5932511d56fe68b7039d15977f7f6/core/chaincode/lifecycle/serializer.go#L87-L123","documentation":"Any struct field whose kind is not string, int64, slice-of-bytes, or proto pointer falls into the default branch of SerializableChecks and is rejected with this error, which reports the offending kind and field name. This is the terminal validation for unsupported field kinds.","triggerScenarios":"Fields of kind bool, float64, uint64, map, interface, struct (non-pointer), etc. in a struct handed to Serialize/IsSerialized/IsMetadataSerialized/Deserialize.","commonSituations":"Using bool flags or map[string]string fields in chaincode metadata structs; switching an int64 field to uint64 or float64 during refactoring.","solutions":["Convert unsupported fields to int64 (integers), string, []byte, or proto pointer","Encode bools/maps into []byte via json.Marshal before serializing","Audit the struct so every field kind matches the serializer's supported set"],"exampleFix":"// before\ntype Def struct { Enabled bool; Labels map[string]string }\n// after\ntype Def struct { EnabledBytes []byte; LabelsBytes []byte } // json.Marshal encoded","handlingStrategy":"validation","validationCode":"func checkFieldKinds(v any) error {\n  t := reflect.TypeOf(v).Elem()\n  for i := 0; i < t.NumField(); i++ {\n    k := t.Field(i).Type.Kind()\n    switch k {\n    case reflect.String, reflect.Int64, reflect.Slice, reflect.Pointer:\n    default:\n      return fmt.Errorf(\"field %s kind %v unsupported\", t.Field(i).Name, k)\n    }\n  }\n  return nil\n}","typeGuard":"func isSerializableKind(k reflect.Kind) bool {\n  return k == reflect.String || k == reflect.Int64 || k == reflect.Slice || k == reflect.Pointer\n}","tryCatchPattern":"_, _, err := s.SerializableChecks(input)\nif err != nil && strings.Contains(err.Error(), \"unsupported structure field kind\") {\n  // replace the offending field with a supported kind\n}","preventionTips":["Restrict state struct fields to string, int64, []byte, proto pointer","Encode bools/floats/maps as bytes before serializing","Validate structs in CI before shipping chaincode changes"],"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"}