XINCGer/Unity3DTraining · error · InvalidProtocolBufferException

Repeated field value was not an array. Token type:

Error message

Repeated field value was not an array. Token type: 

What it means

For a repeated proto field, canonical JSON requires the value to be an array. JsonParser.MergeRepeatedField reads the next token and throws InvalidProtocolBufferException if it is not a start-array token, reporting the actual token type encountered.

Solutions

  1. Wrap the value in a JSON array: change "field": value to "field": [value]
  2. Update the producer so repeated fields are always serialized as arrays (canonical proto JSON)
  3. Accept and normalize non-array values in your own pre-processing layer before calling JsonParser
  4. If the field was recently made repeated, version the API or keep a singular field temporarily

Example fix

// before
{ "tags": "prod" }
// after
{ "tags": ["prod"] }
Defensive patterns

Strategy: validation

Validate before calling

// Ensure repeated fields are arrays before parsing
static bool IsArrayValue(string json, string repeatedFieldName) { using var doc = System.Text.Json.JsonDocument.Parse(json); return !doc.RootElement.TryGetProperty(repeatedFieldName, out var v) || v.ValueKind == System.Text.Json.JsonValueKind.Array; }

Try / catch

try { return parser.Parse<T>(json); } catch (InvalidProtocolBufferException ex) when (ex.Message.StartsWith("Repeated field value was not an array")) { log.Error("Repeated field given a scalar instead of an array"); throw new BadRequestException(ex.Message, ex); }

Prevention

When it happens

Trigger: Parsing JSON where a repeated field is given a single scalar instead of an array — e.g. {"tags": "a"} instead of {"tags": ["a"]}; clients built against an older non-canonical serialization; hand-written JSON omitting the brackets.

Common situations: Hand-crafted test fixtures; JavaScript clients assigning a single value instead of pushing to an array; JSON produced by non-canonical serializers; proto field changed from singular to repeated and old senders not updated.

Related errors


AI-assisted analysis of XINCGer/Unity3DTraining@016f98412e (2026-09-12). Data as JSON: /api/errors/1ba00349822c1dd9. Report an issue: GitHub.

Appendix: source

Thrown at NetWorkAndResources/Socket_Protobuff/Assets/Plugins/Google.Protobuf/JsonParser.cs:251

                MergeMapField(message, field, tokenizer);
            }
            else if (field.IsRepeated)
            {
                MergeRepeatedField(message, field, tokenizer);
            }
            else
            {
                var value = ParseSingleValue(field, tokenizer);
                field.Accessor.SetValue(message, value);
            }
        }

        private void MergeRepeatedField(IMessage message, FieldDescriptor field, JsonTokenizer tokenizer)
        {
            var token = tokenizer.Next();
            if (token.Type != JsonToken.TokenType.StartArray)
            {
                throw new InvalidProtocolBufferException("Repeated field value was not an array. Token type: " + token.Type);
            }

            IList list = (IList)field.Accessor.GetValue(message);
            while (true)
            {
                token = tokenizer.Next();
                if (token.Type == JsonToken.TokenType.EndArray)
                {
                    return;
                }
                tokenizer.PushBack(token);
                if (token.Type == JsonToken.TokenType.Null)
                {
                    throw new InvalidProtocolBufferException("Repeated field elements cannot be null");
                }
                list.Add(ParseSingleValue(field, tokenizer));
            }
        }

View on GitHub (pinned to 016f98412e)