{"record":{"id":"5d191205952ccacb","repo":"XINCGer/Unity3DTraining","slug":"setvalue-is-not-implemented-for-map-fields","errorCode":null,"errorMessage":"SetValue is not implemented for map fields","messagePattern":"SetValue is not implemented for map fields","errorType":"exception","errorClass":"InvalidOperationException","httpStatus":null,"severity":"error","filePath":"NetWorkAndResources/Socket_Protobuff/Assets/Plugins/Google.Protobuf/Reflection/MapFieldAccessor.cs","lineNumber":56,"sourceCode":"{\n    /// <summary>\n    /// Accessor for map fields.\n    /// </summary>\n    internal sealed class MapFieldAccessor : FieldAccessorBase\n    {\n        internal MapFieldAccessor(PropertyInfo property, FieldDescriptor descriptor) : base(property, descriptor)\n        {\n        }\n\n        public override void Clear(IMessage message)\n        {\n            IDictionary list = (IDictionary) GetValue(message);\n            list.Clear();\n        }\n\n        public override void SetValue(IMessage message, object value)\n        {\n            throw new InvalidOperationException(\"SetValue is not implemented for map fields\");\n        }\n    }\n}\n","sourceCodeStart":38,"sourceCodeEnd":60,"githubUrl":"https://github.com/XINCGer/Unity3DTraining/blob/016f98412ea5e11756b286736f479b66ab6216d5/NetWorkAndResources/Socket_Protobuff/Assets/Plugins/Google.Protobuf/Reflection/MapFieldAccessor.cs#L38-L60","documentation":"Map fields in Google.Protobuf have no single-value setter: their content is managed through the MapField<TKey,TValue> collection returned by the property getter. MapFieldAccessor.SetValue intentionally throws InvalidOperationException because assigning a whole map object is not a supported operation.","triggerScenarios":"Calling reflection-based SetValue(message, value) on a field descriptor whose accessor is a MapFieldAccessor — e.g. generic reflection/serialization code that writes every field via SetValue, or copying messages field-by-field via descriptors.","commonSituations":"Custom object mappers or JSON/O-RM style code that uses IFieldAccessor.SetValue uniformly for all fields; test helpers that clone messages generically; porting code from runtimes where map setters exist.","solutions":["Cast to MapFieldAccessor (or get the map via GetValue) and mutate the returned IDictionary/MapField: Clear() then Add entries.","In reflection code, special-case IsMap fields: read the map with GetValue and copy its entries instead of calling SetValue.","Use IMessage.MergeFrom or the message's own cloning (e.g. message.Clone()) instead of per-field SetValue for copies.","Check accessor.IsMap before invoking SetValue and branch accordingly."],"exampleFix":"// before\naccessor.SetValue(message, sourceMapObject); // throws for map fields\n// after\nvar target = (IDictionary)accessor.GetValue(message);\ntarget.Clear();\nforeach (var key in ((IDictionary)sourceMapObject).Keys) target[key] = ((IDictionary)sourceMapObject)[key];","handlingStrategy":"type-guard","validationCode":"if (accessor is MapFieldAccessor) { /* use GetValue + IDictionary mutation */ }","typeGuard":"bool IsMapField(IFieldAccessor a) => a is MapFieldAccessor;","tryCatchPattern":"try { accessor.SetValue(msg, v); } catch (InvalidOperationException e) when (e.Message.Contains(\"map fields\")) { CopyMapEntries((IDictionary)accessor.GetValue(msg), v); }","preventionTips":["Never call SetValue on map fields; mutate the MapField via GetValue.","Special-case IsMap in any generic reflection-based copy/serialization code.","Prefer message.Clone()/MergeFrom over per-field SetValue for copying."],"tags":["protobuf","reflection","maps","unsupported-operation"],"backgroundTag":"method-not-implemented","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"}