XINCGer/Unity3DTraining · error · DescriptorValidationException

"TypeName" is not a message type.

Error message

"TypeName" is not a message type.

What it means

During CrossLink, if the field's resolved type is FieldType.Message, the type_name must resolve to a MessageDescriptor. If the pool lookup returned an EnumDescriptor (or any other symbol), the field claims to be a message but its name names an enum, so DescriptorValidationException is thrown.

Solutions

  1. Change the field's declared type so Type = TYPE_ENUM if it references an enum (or point TypeName at a real message) and regenerate.
  2. Regenerate all descriptors from the .proto sources so Type and TypeName stay consistent.
  3. Validate before CrossLink: resolve TypeName and check the descriptor kind matches the declared Type.

Example fix

// before (proto)
optional MyEnum field = 1; // but Type set to TYPE_MESSAGE
// after
optional MyEnum field = 1; // with Type = TYPE_ENUM
Defensive patterns

Strategy: validation

Validate before calling

if (field.Proto.Type == FieldDescriptorProto.Types.Type.Message)
{
    var sym = pool.FindSymbol(field.Proto.TypeName);
    if (!(sym is MessageDescriptor)) throw new InvalidDataException(field.Proto.TypeName + " is not a message");
}

Type guard

bool IsMessageField(FieldDescriptorProto f, DescriptorPool pool) =>
    f.Type != FieldDescriptorProto.Types.Type.Message || pool.FindSymbol(f.TypeName) is MessageDescriptor;

Try / catch

try { descriptor = FileDescriptor.BuildFromByteStrings(data); }
catch (DescriptorValidationException ex) when (ex.Message.Contains("is not a message type"))
{ log.LogError(ex, "Type/TypeName mismatch on field"); }

Prevention

When it happens

Trigger: A field with Type = TYPE_MESSAGE whose TypeName resolves to an enum in the descriptor pool — typically a proto where the field type keyword and the referenced type disagree (e.g. editing the Type enum manually in a generated FileDescriptorProto).

Common situations: Post-processing generated descriptors and changing Type without changing TypeName; .proto where 'message X' was converted to 'enum X' but dependents not regenerated.

Understand the failure class

Background: "is not a compatible type" / "cannot merge" errors: when a value's type doesn't match what the library requires — this error's family across 65 libraries.

Related errors


AI-assisted analysis of XINCGer/Unity3DTraining@016f98412e (2026-09-12). Data as JSON: /api/errors/11ffb8081964e9b8. Report an issue: GitHub.

Appendix: source

Thrown at NetWorkAndResources/Socket_Protobuff/Assets/Plugins/Google.Protobuf/Reflection/FieldDescriptor.cs:325

                    if (typeDescriptor is MessageDescriptor)
                    {
                        fieldType = FieldType.Message;
                    }
                    else if (typeDescriptor is EnumDescriptor)
                    {
                        fieldType = FieldType.Enum;
                    }
                    else
                    {
                        throw new DescriptorValidationException(this, "\"" + Proto.TypeName + "\" is not a type.");
                    }
                }

                if (fieldType == FieldType.Message)
                {
                    if (!(typeDescriptor is MessageDescriptor))
                    {
                        throw new DescriptorValidationException(this, "\"" + Proto.TypeName + "\" is not a message type.");
                    }
                    messageType = (MessageDescriptor)typeDescriptor;

                    if (Proto.DefaultValue != "")
                    {
                        throw new DescriptorValidationException(this, "Messages can't have default values.");
                    }
                }
                else if (fieldType == FieldType.Enum)
                {
                    if (!(typeDescriptor is EnumDescriptor))
                    {
                        throw new DescriptorValidationException(this, "\"" + Proto.TypeName + "\" is not an enum type.");
                    }
                    enumType = (EnumDescriptor)typeDescriptor;
                }
                else
                {

View on GitHub (pinned to 016f98412e)