XINCGer/Unity3DTraining · error · InvalidProtocolBufferException
Invalid numeric value for type:
Error message
Invalid numeric value for type:
What it means
After passing the grammar checks, ParseNumericString invokes the actual parser (int.Parse/long.Parse/double.Parse via delegate) with invariant culture. A FormatException means the text, while superficially numeric-looking, is not parseable as the target CLR type (e.g. embedded whitespace, multiple decimal points, trailing garbage). The library rethrows it as InvalidProtocolBufferException('Invalid numeric value for type: ' + text).
Solutions
- Validate/normalize the numeric string before embedding it in JSON (strip separators, use '.' as decimal point)
- Use CultureInfo.InvariantCulture when converting numbers to strings for JSON
- Parse the value yourself first (int.TryParse/InvariantCulture) and serialize the typed value, not the raw string
- Check which proto field type the token targets and match its expected textual form (integer vs decimal vs exponent)
Example fix
// before
string json = "{\"amount\": " + amount.ToString("N2") + "}"; // "1,234.50"
// after
string json = "{\"amount\": " + amount.ToString(CultureInfo.InvariantCulture) + "}"; // 1234.5 Defensive patterns
Strategy: validation
Validate before calling
bool IsCleanNumber(string text) =>
double.TryParse(text, NumberStyles.Float, CultureInfo.InvariantCulture, out _); Try / catch
try { return JsonParser.Default.Parse<T>(json); }
catch (InvalidProtocolBufferException ex) when (ex.Message.StartsWith("Invalid numeric value for type")) {
logger.LogWarning(ex, "Non-parseable numeric token");
return null;
} Prevention
- Always convert numbers to strings with CultureInfo.InvariantCulture
- Strip locale separators (spaces, thousands separators) before embedding in JSON
- Parse-then-serialize typed values instead of concatenating raw strings
When it happens
Trigger: JsonParser.Parse<T> with numeric tokens like '1 000', '1.2.3', '0x1F', '1_000', or a double-formatted token for an int-typed field where the parser delegate expects an integer form.
Common situations: Numbers scraped from UIs with thousand separators or spaces; hex or underscore literals copied from source code; locale-formatted strings (comma decimal separator) leaking into JSON; template concatenation mistakes.
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
- Invalid numeric value:
- Value out of range
- 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/9a6a3d648f2b756b.
Report an issue: GitHub.
Appendix: source
Thrown at NetWorkAndResources/Socket_Protobuff/Assets/Plugins/Google.Protobuf/JsonParser.cs:760
if (text[1] >= '0' && text[1] <= '9')
{
throw new InvalidProtocolBufferException("Invalid numeric value: " + text);
}
}
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"))
{View on GitHub (pinned to 016f98412e)