XINCGer/Unity3DTraining · error · InvalidProtocolBufferException

Expected an object

Error message

Expected an object

What it means

JsonParser.Merge expects the next token for a message to be a start-object token ('{'), since a protobuf message maps to a JSON object. Well-known types (Timestamp, wrappers, Any, etc.) get special handling first; anything left falls through to this check and throws InvalidProtocolBufferException if the token is not '{'.

Solutions

  1. Confirm the JSON input is a top-level object '{ ... }' matching the target message type
  2. Parse scalar/array values into the matching field, not into the message itself
  3. Check that the target message type matches the JSON producer's schema version
  4. Inspect the raw JSON (log first 100 chars) to see what token actually appears

Example fix

// before
var msg = parser.Parse<User>("[{'id':1}]"); // array, not object
// after
var msg = parser.Parse<User>("{'id': 1}");
Defensive patterns

Strategy: validation

Validate before calling

static bool IsJsonObject(string json) { var t = json.TrimStart(); return t.StartsWith("{"); }

Try / catch

try { return parser.Parse<T>(json); } catch (InvalidProtocolBufferException ex) when (ex.Message == "Expected an object") { log.Error($"Expected JSON object for {typeof(T).Name}"); throw new BadRequestException("Message JSON must be an object", ex); }

Prevention

When it happens

Trigger: Parsing a JSON array, string, number, or null where a message object is expected — e.g. passing the JSON for a field's value directly to a top-level Parse call, or assigning a scalar JSON value to a message-typed field.

Common situations: Passing a JSON array of messages to Parse instead of a single object; wiring JSON produced for a nested field to the wrong message type; a client sending null or a quoted string where an object body was expected; wrong wrapper-type assumptions.

Understand the failure class

Background: "cannot parse invalid wire-format data", "cannot unmarshal", "failed unmarshalling": protobuf unmarshal errors explained — this error's family across 10 libraries.

Related errors


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

Appendix: source

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

        {
            if (tokenizer.ObjectDepth > settings.RecursionLimit)
            {
                throw InvalidProtocolBufferException.JsonRecursionLimitExceeded();
            }
            if (message.Descriptor.IsWellKnownType)
            {
                Action<JsonParser, IMessage, JsonTokenizer> handler;
                if (WellKnownTypeHandlers.TryGetValue(message.Descriptor.FullName, out handler))
                {
                    handler(this, message, tokenizer);
                    return;
                }
                // Well-known types with no special handling continue in the normal way.
            }
            var token = tokenizer.Next();
            if (token.Type != JsonToken.TokenType.StartObject)
            {
                throw new InvalidProtocolBufferException("Expected an object");
            }
            var descriptor = message.Descriptor;
            var jsonFieldMap = descriptor.Fields.ByJsonName();
            // All the oneof fields we've already accounted for - we can only see each of them once.
            // The set is created lazily to avoid the overhead of creating a set for every message
            // we parsed, when oneofs are relatively rare.
            HashSet<OneofDescriptor> seenOneofs = null;
            while (true)
            {
                token = tokenizer.Next();
                if (token.Type == JsonToken.TokenType.EndObject)
                {
                    return;
                }
                if (token.Type != JsonToken.TokenType.Name)
                {
                    throw new InvalidOperationException("Unexpected token type " + token.Type);
                }

View on GitHub (pinned to 016f98412e)