XINCGer/Unity3DTraining · error · InvalidProtocolBufferException
Map values must not be null
Error message
Map values must not be null
What it means
Protobuf map entries cannot have null values: every map entry stores a concrete key and value. When parsing a map field's JSON, if the value token is JSON null (even for message-typed values, where null could conceptually mean an empty message), MergeMapField rejects it with this InvalidProtocolBufferException.
Solutions
- Remove null entries from the map JSON before parsing — an entry whose value is null should either be omitted entirely or given a default/empty value.
- Replace null with the default value for the value type (empty string, 0, empty message object like {}).
- Sanitize dictionaries before serialization: filter out entries with null values before emitting JSON.
- If nulls are meaningful, change the schema to wrap the value in a message with an optional field (e.g. google.protobuf.Value or a wrapper message).
Example fix
// before
{"myMap": {"a": null, "b": 2}}
// after: omit or default the null entry
{"myMap": {"b": 2}} // or {"myMap": {"a": "", "b": 2}} Defensive patterns
Strategy: validation
Validate before calling
// Strip null-valued map entries before parsing
function cleanMap(m) {
return Object.fromEntries(Object.entries(m).filter(([, v]) => v !== null));
}
if (payload.myMap) payload.myMap = cleanMap(payload.myMap); Try / catch
try { var msg = JsonParser.Default.Parse<T>(json); }
catch (InvalidProtocolBufferException ex) when (ex.Message == "Map values must not be null") { /* sanitize payload and retry once */ } Prevention
- Filter null values out of dictionaries before serializing to protobuf JSON
- Treat 'absent key' as the protobuf equivalent of null
- If nulls are meaningful, use wrapper messages with optional fields in the schema
When it happens
Trigger: Calling JsonParser.Parse with JSON like {"myMap": {"key1": null}} — a null as the value of any map entry, regardless of the value type.
Common situations: JSON serialized from dictionaries that contained null values (common in C#/Java maps with nullable reference values); frontend code emitting null for absent values; interop with systems that allow null map values (e.g. OpenAPI-style maps) before feeding protobuf JSON parsing.
Related errors
- Repeated field elements cannot be null
- Expected an object to populate a map
- Haven't worked out what to do for null yet
- Unhandled dictionary key type:
- Expected end of JSON after object
AI-assisted analysis of XINCGer/Unity3DTraining@016f98412e (2026-09-12).
Data as JSON: /api/errors/3ead103a3400a880.
Report an issue: GitHub.
Appendix: source
Thrown at NetWorkAndResources/Socket_Protobuff/Assets/Plugins/Google.Protobuf/JsonParser.cs:300
var valueField = type.FindFieldByNumber(2);
if (keyField == null || valueField == null)
{
throw new InvalidProtocolBufferException("Invalid map field: " + field.FullName);
}
IDictionary dictionary = (IDictionary)field.Accessor.GetValue(message);
while (true)
{
token = tokenizer.Next();
if (token.Type == JsonToken.TokenType.EndObject)
{
return;
}
object key = ParseMapKey(keyField, token.StringValue);
object value = ParseSingleValue(valueField, tokenizer);
if (value == null)
{
throw new InvalidProtocolBufferException("Map values must not be null");
}
dictionary[key] = value;
}
}
private static bool IsGoogleProtobufValueField(FieldDescriptor field)
{
return field.FieldType == FieldType.Message &&
field.MessageType.FullName == Value.Descriptor.FullName;
}
private object ParseSingleValue(FieldDescriptor field, JsonTokenizer tokenizer)
{
var token = tokenizer.Next();
if (token.Type == JsonToken.TokenType.Null)
{
// TODO: In order to support dynamic messages, we should really build this up
// dynamically.View on GitHub (pinned to 016f98412e)