{"record":{"id":"49fdbedc990ba0ae","repo":"XINCGer/Unity3DTraining","slug":"field-with-message-or-enum-type-missing-type-name","errorCode":null,"errorMessage":"Field with message or enum type missing type_name.","messagePattern":"Field with message or enum type missing type_name\\.","errorType":"validation","errorClass":"DescriptorValidationException","httpStatus":null,"severity":"error","filePath":"NetWorkAndResources/Socket_Protobuff/Assets/Plugins/Google.Protobuf/Reflection/FieldDescriptor.cs","lineNumber":351,"sourceCode":"                }\n                else if (fieldType == FieldType.Enum)\n                {\n                    if (!(typeDescriptor is EnumDescriptor))\n                    {\n                        throw new DescriptorValidationException(this, \"\\\"\" + Proto.TypeName + \"\\\" is not an enum type.\");\n                    }\n                    enumType = (EnumDescriptor)typeDescriptor;\n                }\n                else\n                {\n                    throw new DescriptorValidationException(this, \"Field with primitive type has type_name.\");\n                }\n            }\n            else\n            {\n                if (fieldType == FieldType.Message || fieldType == FieldType.Enum)\n                {\n                    throw new DescriptorValidationException(this, \"Field with message or enum type missing type_name.\");\n                }\n            }\n\n            // Note: no attempt to perform any default value parsing\n\n            File.DescriptorPool.AddFieldByNumber(this);\n\n            if (ContainingType != null && ContainingType.Proto.Options != null && ContainingType.Proto.Options.MessageSetWireFormat)\n            {\n                throw new DescriptorValidationException(this, \"MessageSet format is not supported.\");\n            }\n            accessor = CreateAccessor();\n        }\n\n        private IFieldAccessor CreateAccessor()\n        {\n            // If we're given no property name, that's because we really don't want an accessor.\n            // (At the moment, that means it's a map entry message...)","sourceCodeStart":333,"sourceCodeEnd":369,"githubUrl":"https://github.com/XINCGer/Unity3DTraining/blob/016f98412ea5e11756b286736f479b66ab6216d5/NetWorkAndResources/Socket_Protobuff/Assets/Plugins/Google.Protobuf/Reflection/FieldDescriptor.cs#L333-L369","documentation":"During descriptor cross-linking, Google.Protobuf validates every FieldDescriptorProto. If a field's type resolves to FieldType.Message or FieldType.Enum but no type_name was supplied in the .proto/descriptor, the field cannot be linked and CrossLink throws DescriptorValidationException.","triggerScenarios":"Building a FileDescriptor from a FileDescriptorProto (e.g. FileDescriptor.BuildFrom or FromGeneratedCode) where a message/enum-typed field in a DescriptorProto has FieldType.Message or FieldType.Enum but proto.type_name is null or empty.","commonSituations":"Hand-crafted or programmatically mutated FileDescriptorProtos; descriptors serialized by a non-protoc tool that omitted type_name; truncated or manually edited descriptor bytes embedded in generated code.","solutions":["Ensure every message/enum field's FieldDescriptorProto has Type set AND TypeName set to the fully-qualified type name (e.g. \".pkg.MyMessage\").","Regenerate descriptors with protoc instead of constructing them manually.","Validate the descriptor proto before BuildFrom by walking fields and checking TypeName for MESSAGE/ENUM types.","If descriptor data is corrupted, re-embed the descriptor from a fresh protoc run."],"exampleFix":"// before\nvar field = new FieldDescriptorProto { Name = \"item\", Number = 1, Type = FieldDescriptorProto.Type.TypeMessage }; // no TypeName\n// after\nvar field = new FieldDescriptorProto { Name = \"item\", Number = 1, Type = FieldDescriptorProto.Type.TypeMessage, TypeName = \".myproto.Item\" };","handlingStrategy":"validation","validationCode":"bool ValidDescriptor(FileDescriptorProto f) => f.MessageType.All(m => m.Field.All(fd => fd.Type != FieldDescriptorProto.Type.TypeMessage && fd.Type != FieldDescriptorProto.Type.TypeEnum || !string.IsNullOrEmpty(fd.TypeName)));","typeGuard":null,"tryCatchPattern":"try { descriptor.BuildFrom(...); } catch (DescriptorValidationException e) { log.LogError($\"Field {e.Message}: check type_name in descriptor\"); }","preventionTips":["Always generate descriptors with protoc, never hand-build FieldDescriptorProtos for message/enum fields.","Set both Type and TypeName when constructing FieldDescriptorProto programmatically.","Add a unit test that builds all descriptors at startup to fail fast."],"tags":["protobuf","descriptor","reflection","validation"],"backgroundTag":"missing-required-config-field","analyzedSha":"016f98412ea5e11756b286736f479b66ab6216d5","analyzedAt":"2026-09-12T01:08:58.711Z","contentChangedAt":"2026-09-12T01:08:58.711Z","schemaVersion":2},"datasetVersion":"2026-09-16T09:17:16.951Z"}