{"record":{"id":"e38b8e8537e9b7c1","repo":"XINCGer/Unity3DTraining","slug":"fielddescriptorproto-oneof-index-is-out-of-range-f","errorCode":null,"errorMessage":"FieldDescriptorProto.oneof_index is out of range for type {parent.Name}","messagePattern":"FieldDescriptorProto\\.oneof_index is out of range for type (.+?)","errorType":"validation","errorClass":"DescriptorValidationException","httpStatus":null,"severity":"error","filePath":"NetWorkAndResources/Socket_Protobuff/Assets/Plugins/Google.Protobuf/Reflection/FieldDescriptor.cs","lineNumber":87,"sourceCode":"            : base(file, file.ComputeFullName(parent, proto.Name), index)\n        {\n            Proto = proto;\n            if (proto.Type != 0)\n            {\n                fieldType = GetFieldTypeFromProtoType(proto.Type);\n            }\n\n            if (FieldNumber <= 0)\n            {\n                throw new DescriptorValidationException(this, \"Field numbers must be positive integers.\");\n            }\n            ContainingType = parent;\n            // OneofIndex \"defaults\" to -1 due to a hack in FieldDescriptor.OnConstruction.\n            if (proto.OneofIndex != -1)\n            {\n                if (proto.OneofIndex < 0 || proto.OneofIndex >= parent.Proto.OneofDecl.Count)\n                {\n                    throw new DescriptorValidationException(this, \"FieldDescriptorProto.oneof_index is out of range for type \" + parent.Name);\n                }\n                ContainingOneof = parent.Oneofs[proto.OneofIndex];\n            }\n\n            file.DescriptorPool.AddSymbol(this);\n            // We can't create the accessor until we've cross-linked, unfortunately, as we\n            // may not know whether the type of the field is a map or not. Remember the property name\n            // for later.\n            // We could trust the generated code and check whether the type of the property is\n            // a MapField, but that feels a tad nasty.\n            this.propertyName = propertyName;\n            JsonName = Proto.JsonName == \"\" ? JsonFormatter.ToJsonName(Proto.Name) : Proto.JsonName;\n        }\n\n\n        /// <summary>\n        /// The brief name of the descriptor's target.\n        /// </summary>","sourceCodeStart":69,"sourceCodeEnd":105,"githubUrl":"https://github.com/XINCGer/Unity3DTraining/blob/016f98412ea5e11756b286736f479b66ab6216d5/NetWorkAndResources/Socket_Protobuff/Assets/Plugins/Google.Protobuf/Reflection/FieldDescriptor.cs#L69-L105","documentation":"Google.Protobuf throws this DescriptorValidationException while building a FieldDescriptor when the proto's oneof_index does not point at a valid entry in the parent message's oneof declaration list. A field that declares it belongs to a oneof must reference an existing oneof_decl; an index of -1 means 'no oneof' and is handled specially. Any other out-of-range index means the file descriptor is internally inconsistent.","triggerScenarios":"Building descriptor objects from a FileDescriptorSet/proto bytes where a field's oneof_index is negative (other than -1) or >= parent.Proto.OneofDecl.Count, e.g. a hand-edited or corrupted serialized FileDescriptorProto, or programmatically constructed protos where Oneofs were added to the parent after the fields referencing them by index.","commonSituations":"Manually assembling FileDescriptorProto in code and appending fields before their oneof declarations; regenerating descriptors with mismatched toolchain versions; corrupt or tampered descriptor payloads received over the network (this plugin ships in a Unity socket/networking project).","solutions":["Regenerate the descriptor from the authoritative .proto source with protoc so oneof_index values are recomputed consistently.","If building descriptors in code, add all OneofDecl entries to the message proto BEFORE appending fields whose OneofIndex refers to them.","Validate each field's OneofIndex (-1 or 0..OneofDecl.Count-1) against the parent's OneofDecl list before deserializing/constructing descriptors from untrusted data."],"exampleFix":"// before: field added before its oneof decl\nmsg.Field.Add(new FieldDescriptorProto { Name = \"val\", OneofIndex = 0 });\nmsg.OneofDecl.Add(new OneofDescriptorProto { Name = \"choice\" });\n// after: declare the oneof first\nmsg.OneofDecl.Add(new OneofDescriptorProto { Name = \"choice\" });\nmsg.Field.Add(new FieldDescriptorProto { Name = \"val\", OneofIndex = 0 });","handlingStrategy":"validation","validationCode":"bool ok = field.Proto.OneofIndex == -1\n    || (field.Proto.OneofIndex >= 0 && field.Proto.OneofIndex < parent.Proto.OneofDecl.Count);\nif (!ok) throw new InvalidDataException($\"oneof_index {field.Proto.OneofIndex} out of range for {parent.Name}\");","typeGuard":null,"tryCatchPattern":"try { descriptor = FileDescriptor.BuildFromByteStrings(data); }\ncatch (DescriptorValidationException ex) { log.LogError(ex, \"Invalid descriptor: \" + ex.Message); }\n// DescriptorValidationException.Message includes the offending field name.","preventionTips":["Declare oneofs before fields in programmatically built protos.","Always regenerate descriptors with protoc instead of editing serialized bytes.","Validate untrusted descriptor payloads against expected message schemas before use."],"tags":["protobuf","descriptor-validation","oneof"],"backgroundTag":"value-out-of-range","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"}