XINCGer/Unity3DTraining · error · InvalidOperationException
Invalid type argument requested for wrapper codec:
Error message
Invalid type argument requested for wrapper codec:
What it means
WrapperFieldCodec.GetCodec<T> throws InvalidOperationException when T is not one of the supported wrapper value types registered in its static Codecs table. Only the protobuf primitive wrapper value types (e.g. Int32Value, StringValue, BoolValue, BytesValue) have codecs.
Solutions
- Use the corresponding wrapper message type (Int32Value, Int64Value, UInt32Value, UInt64Value, FloatValue, DoubleValue, BoolValue, StringValue, BytesValue) as T
- Use the generated code's built-in codec instead of hand-constructing one
- Wrap the raw value in the wrapper type before creating the codec
- Regenerate code with matching Google.Protobuf runtime version
Example fix
// before var codec = FieldCodec.Wrap<int>(); // after var codec = FieldCodec.Wrap<Int32Value>();
Defensive patterns
Strategy: type-guard
Validate before calling
bool isWrapper = typeof(T) == typeof(Int32Value) || typeof(T) == typeof(Int64Value) || typeof(T) == typeof(UInt32Value) || typeof(T) == typeof(UInt64Value) || typeof(T) == typeof(FloatValue) || typeof(T) == typeof(DoubleValue) || typeof(T) == typeof(BoolValue) || typeof(T) == typeof(StringValue) || typeof(T) == typeof(BytesValue);
Type guard
static bool IsWrapperType(Type t) => typeof(IMessage).IsAssignableFrom(t) && t.FullName.StartsWith("Google.Protobuf.WellKnownTypes.") && t.Name.EndsWith("Value"); Try / catch
try { return FieldCodec.Wrap<T>(); } catch (InvalidOperationException) { throw new NotSupportedException($"{typeof(T)} is not a wrapper value type"); } Prevention
- Only use wrapper message types with FieldCodec.Wrap
- Prefer generated codecs from message code
- Keep generated code and runtime versions in sync
When it happens
Trigger: Calling FieldCodec.Wrap<T> (GetCodec<T>) with a type argument that is not a Google.Protobuf.WellKnownTypes wrapper message, e.g. GetCodec<int> or a custom message type.
Common situations: Hand-writing FieldCodec instances for map/repeated wrapper fields with the wrong generic parameter; code generation mismatch between proto syntax (proto2 optional scalars) and runtime; reflection-driven code building codecs by Type.
Understand the failure class
Background: "Must be a positive integer", "Invalid value", "Unsupported": the invalid-argument-value error family, when a library rejects the value you pass — this error's family across 35 libraries.
Related errors
- Offset must be within the buffer
- Length must be non-negative and within the buffer
- Stream.Read returned a negative count
- SpaceLeft can only be called on CodedOutputStreams that are…
- Key already exists in map
AI-assisted analysis of XINCGer/Unity3DTraining@016f98412e (2026-09-12).
Data as JSON: /api/errors/dc647e8a4d34c076.
Report an issue: GitHub.
Appendix: source
Thrown at NetWorkAndResources/Socket_Protobuff/Assets/Plugins/Google.Protobuf/FieldCodec.cs:288
{ typeof(long), ForInt64(WireFormat.MakeTag(WrappersReflection.WrapperValueFieldNumber, WireFormat.WireType.Varint)) },
{ typeof(uint), ForUInt32(WireFormat.MakeTag(WrappersReflection.WrapperValueFieldNumber, WireFormat.WireType.Varint)) },
{ typeof(ulong), ForUInt64(WireFormat.MakeTag(WrappersReflection.WrapperValueFieldNumber, WireFormat.WireType.Varint)) },
{ typeof(float), ForFloat(WireFormat.MakeTag(WrappersReflection.WrapperValueFieldNumber, WireFormat.WireType.Fixed32)) },
{ typeof(double), ForDouble(WireFormat.MakeTag(WrappersReflection.WrapperValueFieldNumber, WireFormat.WireType.Fixed64)) },
{ typeof(string), ForString(WireFormat.MakeTag(WrappersReflection.WrapperValueFieldNumber, WireFormat.WireType.LengthDelimited)) },
{ typeof(ByteString), ForBytes(WireFormat.MakeTag(WrappersReflection.WrapperValueFieldNumber, WireFormat.WireType.LengthDelimited)) }
};
/// <summary>
/// Returns a field codec which effectively wraps a value of type T in a message.
///
/// </summary>
internal static FieldCodec<T> GetCodec<T>()
{
object value;
if (!Codecs.TryGetValue(typeof(T), out value))
{
throw new InvalidOperationException("Invalid type argument requested for wrapper codec: " + typeof(T));
}
return (FieldCodec<T>)value;
}
internal static T Read<T>(CodedInputStream input, FieldCodec<T> codec)
{
int length = input.ReadLength();
int oldLimit = input.PushLimit(length);
uint tag;
T value = codec.DefaultValue;
while ((tag = input.ReadTag()) != 0)
{
if (tag == codec.Tag)
{
value = codec.Read(input);
}
elseView on GitHub (pinned to 016f98412e)