{"record":{"id":"adcdc3017589f89d","repo":"XINCGer/Unity3DTraining","slug":"field-numbers-must-be-positive-integers","errorCode":null,"errorMessage":"Field numbers must be positive integers.","messagePattern":"Field numbers must be positive integers\\.","errorType":"validation","errorClass":"DescriptorValidationException","httpStatus":null,"severity":"error","filePath":"NetWorkAndResources/Socket_Protobuff/Assets/Plugins/Google.Protobuf/Reflection/FieldDescriptor.cs","lineNumber":79,"sourceCode":"        /// but can be overridden using the <c>json_name</c> option in the .proto file.\n        /// </summary>\n        public readonly string JsonName;\n\n        internal readonly FieldDescriptorProto Proto;\n\n        internal FieldDescriptor(FieldDescriptorProto proto, FileDescriptor file,\n                                 MessageDescriptor parent, int index, string propertyName)\n            : 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.","sourceCodeStart":61,"sourceCodeEnd":97,"githubUrl":"https://github.com/XINCGer/Unity3DTraining/blob/016f98412ea5e11756b286736f479b66ab6216d5/NetWorkAndResources/Socket_Protobuff/Assets/Plugins/Google.Protobuf/Reflection/FieldDescriptor.cs#L61-L97","documentation":"FieldDescriptor construction throws DescriptorValidationException when a field's number is zero or negative. In protobuf wire format the field number is encoded together with the wire type in a varint tag; numbers must be positive integers (and by spec between 1 and 2^29 - 1, with 19000-19999 reserved), so FieldDescriptor rejects anything <= 0 immediately.","triggerScenarios":"Building a FileDescriptor from a FieldDescriptorProto whose Number was never set (defaults to 0) or was explicitly set to a negative value — typically a programmatically built field where Number was forgotten, since protoc never emits such values.","commonSituations":"Dynamic schema builders adding fields without assigning numbers; copy/pasting descriptor construction code and omitting Number; descriptors round-tripped through custom serialization that dropped the number field; auto-numbering logic starting at 0 instead of 1.","solutions":["Assign a positive Number (>= 1) to every FieldDescriptorProto before building the FileDescriptor.","Fix auto-numbering logic to start at 1 and increment per message (or track the max used number).","Stay within the valid range 1 to 536,870,911 and avoid the reserved 19000-19999 range to prevent later failures.","Validate descriptor protos before building (assert FieldNumber > 0 for each field)."],"exampleFix":"// before\nvar field = new FieldDescriptorProto { Name = \"id\", Type = FieldDescriptorProto.Types.Type.Int32 }; // Number defaults to 0\n// after\nvar field = new FieldDescriptorProto { Name = \"id\", Number = 1, Type = FieldDescriptorProto.Types.Type.Int32 };","handlingStrategy":"validation","validationCode":"static void AssertFieldNumbersPositive(DescriptorProto msg)\n{\n    foreach (var f in msg.Fields)\n        if (f.Number <= 0)\n            throw new InvalidOperationException($\"Field {f.Name} in {msg.Name} has invalid number {f.Number}\");\n}","typeGuard":"bool HasValidFieldNumber(FieldDescriptorProto f) => f.Number > 0 && f.Number <= 536870911;","tryCatchPattern":"try\n{\n    var fd = FileDescriptor.BuildFromByteString(bytes, dependencies);\n}\ncatch (DescriptorValidationException ex) when (ex.Message.Contains(\"must be positive integers\"))\n{\n    // assign numbers and rebuild the descriptor\n}","preventionTips":["Always set Number in FieldDescriptorProto initializers","Use an allocator that starts at 1 and respects the reserved 19000-19999 range","Validate all field numbers (1..536870911) before building descriptors"],"tags":["protobuf","descriptor","field-number","validation","csharp"],"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"}