XINCGer/Unity3DTraining · error · InvalidProtocolBufferException

Unsupported conversion from JSON number for field type

Error message

Unsupported conversion from JSON number for field type 

What it means

ParseSingleNumberValue only supports JSON numbers for numeric field types (int/uint/float/double/enum). If a field's FieldType is non-numeric (e.g. string, bytes, message), the switch reaches default and throws this InvalidProtocolBufferException.

Solutions

  1. Fix the JSON so the field's JSON type matches its schema type (quote numbers for string fields).
  2. Regenerate code so client descriptors match the producer's schema version.
  3. If the producer legitimately changed the type, update the .proto and both sides together.

Example fix

// before (string field 'name')
{"name": 123}
// after
{"name": "123"}
Defensive patterns

Strategy: type-guard

Validate before calling

// Verify JSON value types match field types before parsing
// e.g. for a string field:
var token = JToken.Parse(json)["name"];
if (token != null && token.Type != JTokenType.String)
    throw new FormatException($"Field 'name' must be a JSON string, got {token.Type}");

Type guard

static bool IsJsonStringForStringField(JToken token) => token == null || token.Type == JTokenType.String;

Try / catch

try
{
    var msg = parser.Parse<T>(json);
}
catch (InvalidProtocolBufferException ex) when (ex.Message.StartsWith("Unsupported conversion from JSON number"))
{
    // log schema-mismatch details; align producer/consumer schema versions
}

Prevention

When it happens

Trigger: Parsing JSON where a JSON number is supplied for a field declared as a string, bytes, or message type — e.g. {"name": 123} for a string field, often from a schema mismatch between producer and consumer.

Common situations: API version drift where a field's type changed between schema versions; hand-written JSON assigning numbers to string fields; dynamic descriptors pointing at the wrong field.

Understand the failure class

Background: Type mismatch errors: IllegalArgumentException, TypeError and type guards across 150 open-source libraries — this error's family across 150 libraries.

Related errors


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

Appendix: source

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

                            {
                                if (double.IsPositiveInfinity(value))
                                {
                                    return float.PositiveInfinity;
                                }
                                if (double.IsNegativeInfinity(value))
                                {
                                    return float.NegativeInfinity;
                                }
                                throw new InvalidProtocolBufferException("Value out of range: " + value);
                            }
                            return (float)value;
                        case FieldType.Enum:
                            CheckInteger(value);
                            // Just return it as an int, and let the CLR convert it.
                            // Note that we deliberately don't check that it's a known value.
                            return (int)value;
                        default:
                            throw new InvalidProtocolBufferException("Unsupported conversion from JSON number for field type " + field.FieldType);
                    }
                }
                catch (OverflowException)
                {
                    throw new InvalidProtocolBufferException("Value out of range: " + value);
                }
            }
        }

        private static void CheckInteger(double value)
        {
            if (double.IsInfinity(value) || double.IsNaN(value))
            {
                throw new InvalidProtocolBufferException("Value not an integer: " + value);
            }
            if (value != Math.Floor(value))
            {
                throw new InvalidProtocolBufferException("Value not an integer: " + value);

View on GitHub (pinned to 016f98412e)