XINCGer/Unity3DTraining · error · InvalidProtocolBufferException
Value out of range
Error message
Value out of range: {text} What it means
ParseNumericString catches OverflowException from the underlying type parser (e.g. int.Parse on a value beyond int.MaxValue) and rethrows it as InvalidProtocolBufferException('Value out of range: ' + text). This means the JSON number is grammatically valid but cannot fit the declared proto field type (e.g. 3000000000 for int32, or a double too large for a float field).
Solutions
- Change the proto field to a wider type (int64/uint64 or double) and regenerate the C# classes
- Clamp or validate the value client-side against the target type's MinValue/MaxValue before serializing/parsing
- For big values that must stay int32-typed per an existing schema, transmit them as strings (int64-as-string JSON mapping)
- Use unsigned types (uint32/uint64) if values only overflow because they were meant to be non-negative
Example fix
// before
// proto: int32 id = 1; json: {"id": 3000000000} -> overflow
// after
// proto: int64 id = 1; regenerate stubs, then:
var msg = JsonParser.Default.Parse<Message>("{\"id\": 3000000000}"); Defensive patterns
Strategy: validation
Validate before calling
bool FitsType(long v, string protoType) => protoType switch {
"int32" => v >= int.MinValue && v <= int.MaxValue,
"uint32" => v >= 0 && v <= uint.MaxValue,
"int64" => true,
_ => true
};
// check bounds before serializing into JSON Try / catch
try { return JsonParser.Default.Parse<T>(json); }
catch (InvalidProtocolBufferException ex) when (ex.Message.StartsWith("Value out of range")) {
logger.LogWarning(ex, "Numeric value exceeds field type range");
return null;
} Prevention
- Prefer int64/double in protos when values may grow (IDs, timestamps in ms)
- Clamp or validate against the target type's MinValue/MaxValue before sending
- Use int64-as-string JSON mapping for huge values against fixed schemas
- Document field ranges in the .proto comments
When it happens
Trigger: JsonParser.Parse<T> where a numeric field receives a value outside its type's range: >2^31-1 for int32, >2^63-1 for int64, magnitudes beyond float range for float fields, or negative values for unsigned-typed fields.
Common situations: Server using 64-bit IDs sent into an int32 field; timestamp-like millisecond values exceeding int32; language-agnostic producers assuming 'int' means 64-bit; float fields given double-precision extremes.
Understand the failure class
Background: "value must be between 0 and 1" / "out of range" / "must not be negative" errors: fixing range-validation failures across open-source libraries — this error's family across 42 libraries.
Related errors
- Invalid numeric value:
- Invalid numeric value for type:
- Invalid field type
- Unable to format value of type
- Type registry has no descriptor for type name '
AI-assisted analysis of XINCGer/Unity3DTraining@016f98412e (2026-09-12).
Data as JSON: /api/errors/099f65509c6418c4.
Report an issue: GitHub.
Appendix: source
Thrown at NetWorkAndResources/Socket_Protobuff/Assets/Plugins/Google.Protobuf/JsonParser.cs:764
}
else if (text.StartsWith("-0") && text.Length > 2)
{
if (text[2] >= '0' && text[2] <= '9')
{
throw new InvalidProtocolBufferException("Invalid numeric value: " + text);
}
}
try
{
return parser(text, NumberStyles.AllowLeadingSign | NumberStyles.AllowDecimalPoint | NumberStyles.AllowExponent, CultureInfo.InvariantCulture);
}
catch (FormatException)
{
throw new InvalidProtocolBufferException("Invalid numeric value for type: " + text);
}
catch (OverflowException)
{
throw new InvalidProtocolBufferException("Value out of range: " + text);
}
}
/// <summary>
/// Checks that any infinite/NaN values originated from the correct text.
/// This corrects the lenient whitespace handling of double.Parse/float.Parse, as well as the
/// way that Mono parses out-of-range values as infinity.
/// </summary>
private static void ValidateInfinityAndNan(string text, bool isPositiveInfinity, bool isNegativeInfinity, bool isNaN)
{
if ((isPositiveInfinity && text != "Infinity") ||
(isNegativeInfinity && text != "-Infinity") ||
(isNaN && text != "NaN"))
{
throw new InvalidProtocolBufferException("Invalid numeric value: " + text);
}
}
View on GitHub (pinned to 016f98412e)