{"record":{"id":"b22bb8943349659e","repo":"XINCGer/Unity3DTraining","slug":"invalid-map-field","errorCode":null,"errorMessage":"Invalid map field: ","messagePattern":"Invalid map field: ","errorType":"validation","errorClass":"InvalidProtocolBufferException","httpStatus":null,"severity":"error","filePath":"NetWorkAndResources/Socket_Protobuff/Assets/Plugins/Google.Protobuf/JsonParser.cs","lineNumber":285,"sourceCode":"                list.Add(ParseSingleValue(field, tokenizer));\n            }\n        }\n\n        private void MergeMapField(IMessage message, FieldDescriptor field, JsonTokenizer tokenizer)\n        {\n            // Map fields are always objects, even if the values are well-known types: ParseSingleValue handles those.\n            var token = tokenizer.Next();\n            if (token.Type != JsonToken.TokenType.StartObject)\n            {\n                throw new InvalidProtocolBufferException(\"Expected an object to populate a map\");\n            }\n\n            var type = field.MessageType;\n            var keyField = type.FindFieldByNumber(1);\n            var valueField = type.FindFieldByNumber(2);\n            if (keyField == null || valueField == null)\n            {\n                throw new InvalidProtocolBufferException(\"Invalid map field: \" + field.FullName);\n            }\n            IDictionary dictionary = (IDictionary)field.Accessor.GetValue(message);\n\n            while (true)\n            {\n                token = tokenizer.Next();\n                if (token.Type == JsonToken.TokenType.EndObject)\n                {\n                    return;\n                }\n                object key = ParseMapKey(keyField, token.StringValue);\n                object value = ParseSingleValue(valueField, tokenizer);\n                if (value == null)\n                {\n                    throw new InvalidProtocolBufferException(\"Map values must not be null\");\n                }\n                dictionary[key] = value;\n            }","sourceCodeStart":267,"sourceCodeEnd":303,"githubUrl":"https://github.com/XINCGer/Unity3DTraining/blob/016f98412ea5e11756b286736f479b66ab6216d5/NetWorkAndResources/Socket_Protobuff/Assets/Plugins/Google.Protobuf/JsonParser.cs#L267-L303","documentation":"During map parsing, JsonParser looks up the map entry's key field (number 1) and value field (number 2) on the map entry message type. If either is missing, the field's schema is not a well-formed map entry, and this exception names the offending field via field.FullName. This indicates a descriptor-level problem, not a problem with the JSON input.","triggerScenarios":"Parsing JSON for a message whose field descriptor is marked as a map but whose generated entry type lacks fields 1 and 2 — typically from hand-built descriptors, corrupted/mismatched generated code, or a custom FieldRegistry/CustomTypeRegistry hack, not from standard generated C# code.","commonSituations":"Mixing generated code from different proto file versions where the map entry message was edited; dynamically constructed descriptors (DescriptorProto with a map entry missing field 1 or 2); binary/plugin-generated descriptors that bypass protoc validation.","solutions":["Regenerate the C# code with the current protoc/grpc-csharp plugin so the map entry type has key field 1 and value field 2.","Verify the proto definition uses map<K,V> syntax rather than a hand-crafted entry message missing one of the two fields.","Check descriptor construction code (if building descriptors at runtime) to ensure map_entry messages define both field numbers 1 and 2.","Ensure the Google.Protobuf NuGet package version matches the version the generated code was produced with."],"exampleFix":"// before: hand-built map entry missing value field\nnew MessageProto { Name = \"MyMapEntry\", Fields = { FieldNum1Only } }\n\n// after: regenerate or add both fields\nmessage MyMapEntry { K key = 1; V value = 2; } // via map<K,V> in the parent message","handlingStrategy":"validation","validationCode":"// Sanity-check generated descriptors at startup\nvar field = MyMessage.Descriptor.FindFieldByName(\"myMap\");\nif (field?.MessageType.FindFieldByNumber(1) == null || field?.MessageType.FindFieldByNumber(2) == null)\n    throw new InvalidOperationException($\"Malformed map entry for {field?.FullName}: fields 1/2 missing\");","typeGuard":null,"tryCatchPattern":"try { var msg = JsonParser.Default.Parse<T>(json); }\ncatch (InvalidProtocolBufferException ex) { throw new SchemaIntegrityException(ex.Message); }","preventionTips":["Always regenerate generated code with the same protoc version as the Google.Protobuf package","Never hand-edit generated *_Grpc.cs / *Reflection.cs files","Use map<K,V> syntax instead of hand-crafted map entry messages"],"tags":["protobuf","descriptor","map-field","schema"],"backgroundTag":"internal-invariant-violation","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"}