microsoft/autogen · error · ArgumentException

Input must be a protobuf message.

Error message

Input must be a protobuf message.

What it means

Thrown by ProtobufTypeNameResolver.ResolveTypeName when the input Type does not implement Google.Protobuf.IMessage. The resolver exists only to produce protobuf full type names (Descriptor.FullName), so non-proto types are rejected with an ArgumentException.

Source

Thrown at dotnet/src/Microsoft.AutoGen/Core.Grpc/ProtobufTypeNameResolver.cs:20

// ProtobufTypeNameResolver.cs

using Google.Protobuf;

namespace Microsoft.AutoGen.Core.Grpc;

public class ProtobufTypeNameResolver : ITypeNameResolver
{
    public string ResolveTypeName(Type input)
    {
        if (typeof(IMessage).IsAssignableFrom(input))
        {
            // TODO: Consider changing this to avoid instantiation...
            var protoMessage = (IMessage?)Activator.CreateInstance(input) ?? throw new InvalidOperationException($"Failed to create instance of {input.FullName}");
            return protoMessage.Descriptor.FullName;
        }
        else
        {
            throw new ArgumentException("Input must be a protobuf message.");
        }
    }
}

View on GitHub (pinned to 027ecf0a37)

Solutions

  1. Only resolve type names for protobuf-generated message types with this resolver
  2. Route non-proto types to a different ITypeNameResolver implementation (e.g. one returning the CLR full name)
  3. Guard call sites with typeof(IMessage).IsAssignableFrom(t) before invoking

Example fix

// before
var name = protobufResolver.ResolveTypeName(typeof(MyDto));

// after
var name = typeof(IMessage).IsAssignableFrom(typeof(MyDto))
    ? protobufResolver.ResolveTypeName(typeof(MyDto))
    : clrResolver.ResolveTypeName(typeof(MyDto));
Defensive patterns

Strategy: type-guard

Validate before calling

if (!typeof(IMessage).IsAssignableFrom(input)) throw new ArgumentException($"{input.FullName} is not a protobuf message; use a CLR type-name resolver");

Type guard

static bool IsProtobufType(Type t) => typeof(Google.Protobuf.IMessage).IsAssignableFrom(t);

Try / catch

try { return protobufResolver.ResolveTypeName(type); } catch (ArgumentException) { return clrResolver.ResolveTypeName(type); }

Prevention

When it happens

Trigger: Calling ResolveTypeName(typeof(SomePoco)) or passing an interface/non-message class; wiring ProtobufTypeNameResolver as the global ITypeNameResolver in a mixed proto/POCO system.

Common situations: Registering the protobuf resolver too broadly in DI so it resolves names for JSON messages too; scanning assemblies and feeding every exported type to the resolver.

Related errors


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