XINCGer/Unity3DTraining · error · InvalidProtocolBufferException

Expected end-object token after @type/value for well-known…

Error message

Expected end-object token after @type/value for well-known type

What it means

After merging the 'value' property of an Any-wrapped well-known type, the parser requires the JSON object to terminate with an EndObject token. Extra/missing braces or trailing content inside the Any body cause this InvalidProtocolBufferException.

Solutions

  1. Validate the JSON is well-formed and the Any object closes correctly (pass it through a JSON validator first).
  2. Fix braces so the Any body object ends right after the value property.
  3. Check the producer's serializer output — regenerate with a spec-compliant protobuf JSON serializer.

Example fix

// before
{"@type":"type.googleapis.com/google.protobuf.Struct","value":{"a":1}
// after
{"@type":"type.googleapis.com/google.protobuf.Struct","value":{"a":1}}
Defensive patterns

Strategy: validation

Validate before calling

// Ensure the payload is well-formed JSON before protobuf parsing
JToken.Parse(json); // throws Newtonsoft.Json.JsonReaderException on malformed JSON

Type guard

static bool IsWellFormedJson(string json)
{
    try { JToken.Parse(json); return true; }
    catch (JsonReaderException) { return false; }
}

Try / catch

try
{
    var msg = parser.Parse<T>(json);
}
catch (InvalidProtocolBufferException ex) when (ex.Message.Contains("Expected end-object token"))
{
    // treat payload as corrupted; request retransmission or log for forensics
}

Prevention

When it happens

Trigger: Parsing Any JSON where the well-known-type body has a nested object mismatch — e.g. {'@type':..., 'value':{...}} missing a closing brace, or an extra property/object token left before the object ends.

Common situations: Malformed or truncated JSON produced by a buggy serializer; manual string concatenation building Any JSON; copy/paste errors in hand-written test fixtures.

Understand the failure class

Background: JSON parse error: "Unexpected token" / "not valid JSON" / "failed to parse" — what JSON parsers are really complaining about — this error's family across 45 libraries.

Related errors


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

Appendix: source

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

        }

        // Well-known types end up in a property called "value" in the JSON. As there's no longer a @type property
        // in the given JSON token stream, we should *only* have tokens of start-object, name("value"), the value
        // itself, and then end-object.
        private void MergeWellKnownTypeAnyBody(IMessage body, JsonTokenizer tokenizer)
        {
            var token = tokenizer.Next(); // Definitely start-object; checked in previous method
            token = tokenizer.Next();
            // TODO: What about an absent Int32Value, for example?
            if (token.Type != JsonToken.TokenType.Name || token.StringValue != JsonFormatter.AnyWellKnownTypeValueField)
            {
                throw new InvalidProtocolBufferException("Expected '" + JsonFormatter.AnyWellKnownTypeValueField + "' property for well-known type Any body");
            }
            Merge(body, tokenizer);
            token = tokenizer.Next();
            if (token.Type != JsonToken.TokenType.EndObject)
            {
                throw new InvalidProtocolBufferException("Expected end-object token after @type/value for well-known type");
            }
        }

        #region Utility methods which don't depend on the state (or settings) of the parser.
        private static object ParseMapKey(FieldDescriptor field, string keyText)
        {
            switch (field.FieldType)
            {
                case FieldType.Bool:
                    if (keyText == "true")
                    {
                        return true;
                    }
                    if (keyText == "false")
                    {
                        return false;
                    }
                    throw new InvalidProtocolBufferException("Invalid string for bool map key: " + keyText);

View on GitHub (pinned to 016f98412e)