XINCGer/Unity3DTraining · error · ArgumentException
Unable to format value of type
Error message
Unable to format value of type
What it means
JsonFormatter.WriteValue throws ArgumentException when the runtime value is not one of the types the formatter can serialize (bool, numeric types, string, ByteString, IMessage, enumerables, IFormattable enums, etc.). The formatter is strictly typed and refuses unknown object shapes.
Solutions
- Ensure messages are generated Google.Protobuf types (implement IMessage properly)
- Convert unsupported values (e.g. DateTime) to protobuf-compatible types or well-known wrappers (Timestamp/Duration) before formatting
- Check any custom WriteValue/WriteWellKnownTypeValue extension code for passing raw objects
- Use a custom JsonFormatter.Settings formatter hook for exotic values
Example fix
// before writer.WriteValue(myDateTime); // after var ts = Timestamp.FromDateTime(myDateTime); formatter.Format(ts, writer);
Defensive patterns
Strategy: try-catch
Validate before calling
// ensure field values are protobuf-native types before formatting
if (value is IMessage || value is string || value is int || value is long || value is float || value is double || value is bool || value is ByteString) { formatter.Format(msg); } Try / catch
try { writer = formatter.Format(msg); } catch (ArgumentException ex) { /* handle unsupported value type: ex.Message contains the type */ } Prevention
- Use only generated message types and scalar wrappers
- Convert DateTime/Decimal to Timestamp/Duration well-known types
- Avoid injecting foreign objects via reflection
When it happens
Trigger: Formatting a message field whose runtime value is an unsupported CLR type, e.g. a custom class, DateTime, or a null-adjacent value that fell through all type checks in WriteValue's if/else chain.
Common situations: Custom message implementations not derived from generated IMessage<T> code; inserting foreign objects into maps/lists of a message via reflection; writing custom well-known-type handlers that pass raw values to WriteValue.
Related errors
- Invalid field type
- Type registry has no descriptor for type name '
- Struct fields cannot have an empty key or a null value.
- Value message must contain a value for the oneof.
- Unexpected case in struct field:
AI-assisted analysis of XINCGer/Unity3DTraining@016f98412e (2026-09-12).
Data as JSON: /api/errors/36820488c752ce2b.
Report an issue: GitHub.
Appendix: source
Thrown at NetWorkAndResources/Socket_Protobuff/Assets/Plugins/Google.Protobuf/JsonFormatter.cs:414
string text = ((IFormattable)value).ToString("r", CultureInfo.InvariantCulture);
if (text == "NaN" || text == "Infinity" || text == "-Infinity")
{
writer.Write('"');
writer.Write(text);
writer.Write('"');
}
else
{
writer.Write(text);
}
}
else if (value is IMessage)
{
Format((IMessage)value, writer);
}
else
{
throw new ArgumentException("Unable to format value of type " + value.GetType());
}
}
/// <summary>
/// Central interception point for well-known type formatting. Any well-known types which
/// don't need special handling can fall back to WriteMessage. We avoid assuming that the
/// values are using the embedded well-known types, in order to allow for dynamic messages
/// in the future.
/// </summary>
private void WriteWellKnownTypeValue(TextWriter writer, MessageDescriptor descriptor, object value)
{
// Currently, we can never actually get here, because null values are always handled by the caller. But if we *could*,
// this would do the right thing.
if (value == null)
{
WriteNull(writer);
return;
}View on GitHub (pinned to 016f98412e)