{"record":{"id":"17cf879b7af795fc","repo":"XINCGer/Unity3DTraining","slug":"expected-an-object","errorCode":null,"errorMessage":"Expected an object","messagePattern":"Expected an object","errorType":"validation","errorClass":"InvalidProtocolBufferException","httpStatus":null,"severity":"error","filePath":"NetWorkAndResources/Socket_Protobuff/Assets/Plugins/Google.Protobuf/JsonParser.cs","lineNumber":168,"sourceCode":"        {\n            if (tokenizer.ObjectDepth > settings.RecursionLimit)\n            {\n                throw InvalidProtocolBufferException.JsonRecursionLimitExceeded();\n            }\n            if (message.Descriptor.IsWellKnownType)\n            {\n                Action<JsonParser, IMessage, JsonTokenizer> handler;\n                if (WellKnownTypeHandlers.TryGetValue(message.Descriptor.FullName, out handler))\n                {\n                    handler(this, message, tokenizer);\n                    return;\n                }\n                // Well-known types with no special handling continue in the normal way.\n            }\n            var token = tokenizer.Next();\n            if (token.Type != JsonToken.TokenType.StartObject)\n            {\n                throw new InvalidProtocolBufferException(\"Expected an object\");\n            }\n            var descriptor = message.Descriptor;\n            var jsonFieldMap = descriptor.Fields.ByJsonName();\n            // All the oneof fields we've already accounted for - we can only see each of them once.\n            // The set is created lazily to avoid the overhead of creating a set for every message\n            // we parsed, when oneofs are relatively rare.\n            HashSet<OneofDescriptor> seenOneofs = null;\n            while (true)\n            {\n                token = tokenizer.Next();\n                if (token.Type == JsonToken.TokenType.EndObject)\n                {\n                    return;\n                }\n                if (token.Type != JsonToken.TokenType.Name)\n                {\n                    throw new InvalidOperationException(\"Unexpected token type \" + token.Type);\n                }","sourceCodeStart":150,"sourceCodeEnd":186,"githubUrl":"https://github.com/XINCGer/Unity3DTraining/blob/016f98412ea5e11756b286736f479b66ab6216d5/NetWorkAndResources/Socket_Protobuff/Assets/Plugins/Google.Protobuf/JsonParser.cs#L150-L186","documentation":"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 '{'.","triggerScenarios":"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.","commonSituations":"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.","solutions":["Confirm the JSON input is a top-level object '{ ... }' matching the target message type","Parse scalar/array values into the matching field, not into the message itself","Check that the target message type matches the JSON producer's schema version","Inspect the raw JSON (log first 100 chars) to see what token actually appears"],"exampleFix":"// before\nvar msg = parser.Parse<User>(\"[{'id':1}]\"); // array, not object\n// after\nvar msg = parser.Parse<User>(\"{'id': 1}\");","handlingStrategy":"validation","validationCode":"static bool IsJsonObject(string json) { var t = json.TrimStart(); return t.StartsWith(\"{\"); }","typeGuard":null,"tryCatchPattern":"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); }","preventionTips":["Confirm the JSON shape matches the target message type before parsing","Parse field values into their own types, not into the message","Log a snippet of the input on failure to identify arrays/scalars passed by mistake"],"tags":["protobuf","json-parsing","type-mismatch","expected-object"],"backgroundTag":"protobuf-unmarshal-failed","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"}