microsoft/autogen · error · ArgumentException

Message must be a proto IMessage

Error message

Message must be a proto IMessage

What it means

Thrown by ProtobufMessageSerializer.Serialize when the object passed in does not implement Google.Protobuf.IMessage. Serialization is done via Any.Pack(protoMessage), which requires a protobuf message instance; any other CLR object is rejected.

Source

Thrown at dotnet/src/Microsoft.AutoGen/Core.Grpc/ProtobufMessageSerializer.cs:44

            var nameOfMethod = nameof(Any.Unpack);
            var result = message.GetType().GetMethods().Where(m => m.Name == nameOfMethod && m.IsGenericMethod).First().MakeGenericMethod(_concreteType).Invoke(message, null);
            return result as IMessage ?? throw new ArgumentException("Failed to deserialize", nameof(message));
        }

        // Raise an exception if the concrete type is not a proto IMessage
        throw new ArgumentException("Concrete type must be a proto IMessage", nameof(_concreteType));
    }

    public Any Serialize(object message)
    {
        // Check if message is a proto IMessage
        if (message is IMessage protoMessage)
        {
            return Any.Pack(protoMessage);
        }

        // Raise an exception if the message is not a proto IMessage
        throw new ArgumentException("Message must be a proto IMessage", nameof(message));
    }
}

View on GitHub (pinned to 027ecf0a37)

Solutions

  1. Pass protobuf-generated message instances to Serialize/publish
  2. Register a serializer appropriate to the message kind (e.g. JSON serializer for POCOs) so the registry picks the right one
  3. Add a compile-time constraint or generic guard so non-proto messages cannot reach the protobuf path

Example fix

// before
serializer.Serialize(new MyDto { Id = 1 });

// after
serializer.Serialize(new MyProtoMessage { Id = 1 });
Defensive patterns

Strategy: type-guard

Validate before calling

if (message is not Google.Protobuf.IMessage) throw new ArgumentException("Use a JSON serializer for non-proto messages");

Type guard

static bool IsProtobufMessage(object msg) => msg is Google.Protobuf.IMessage;

Try / catch

try { return serializer.Serialize(message); } catch (ArgumentException ex) when (ex.Message.Contains("must be a proto IMessage")) { return jsonSerializer.Serialize(message); }

Prevention

When it happens

Trigger: Calling Serialize with a POCO, anonymous object, string, or JSON-serialized byte payload instead of a protobuf message; a generic publish path routing non-proto messages into the protobuf serializer.

Common situations: Publishing domain DTOs through a runtime configured only with the protobuf serializer; migration from JSON-based messages to protobuf where some call sites still send POCOs.

Related errors


AI-assisted analysis of microsoft/autogen@027ecf0a37 (2026-08-15). Data as JSON: /api/errors/03db3917b7a93e8d. Report an issue: GitHub.