microsoft/autogen · error · ArgumentException

Failed to deserialize

Error message

Failed to deserialize

What it means

Thrown by ProtobufMessageSerializer.Deserialize when reflection-based Any.Unpack<T> for the configured concrete type returns null. Unpack fails (or returns null after casting) when the Any payload's type URL does not match the concrete proto type, or the payload bytes cannot be parsed as that message type.

Source

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

/// Interface for serializing and deserializing agent messages.
/// </summary>
public class ProtobufMessageSerializer : IProtobufMessageSerializer
{
    private System.Type _concreteType;

    public ProtobufMessageSerializer(System.Type concreteType)
    {
        _concreteType = concreteType;
    }

    public object Deserialize(Any message)
    {
        // Check if the concrete type is a proto IMessage
        if (typeof(IMessage).IsAssignableFrom(_concreteType))
        {
            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. Confirm the Any.TypeUrl matches the target message's full proto name (Any.Unpack requires an exact descriptor match)
  2. Regenerate protobuf C# classes from the same .proto files on both sender and receiver
  3. If you must re-map types, unpack to the original type and convert, rather than unpacking bytes as a mismatched type

Example fix

// before
var msg = (MyMessage)serializer.Deserialize(anyPackedAsOtherType); // type URL mismatch

// after
if (any.Is(MyMessage.Descriptor))
{
    var msg = any.Unpack<MyMessage>();
}
else
{
    // resolve correct serializer based on any.TypeUrl
}
Defensive patterns

Strategy: type-guard

Validate before calling

if (!message.Is(_concreteType)) throw new ArgumentException($"Any type URL {message.TypeUrl} does not match target type");

Type guard

static bool CanUnpack(Any any, Type t) => typeof(IMessage).IsAssignableFrom(t) && any.Is((IMessage)Activator.CreateInstance(t)!);

Try / catch

try { return serializer.Deserialize(any); } catch (ArgumentException ex) when (ex.Message == "Failed to deserialize") { throw new InvalidDataException($"Payload {any.TypeUrl} does not match {serializer.ConcreteType}", ex); }

Prevention

When it happens

Trigger: Calling Deserialize with an Any whose type URL names a different message than _concreteType; truncated or corrupted payload bytes; a type-name collision where two messages share a full name across assemblies.

Common situations: Sender and receiver generated protos with different package names; a message type renamed on one side; payload corrupted in transit or re-packed with the wrong descriptor.

Related errors


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