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
- Change the field's declared type so Type = TYPE_ENUM if it references an enum (or point TypeName at a real message) and regenerate.
- Regenerate all descriptors from the .proto sources so Type and TypeName stay consistent.
- 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
- Never hand-edit Type or TypeName in generated descriptor sets; regenerate with protoc.
- When a .proto type changes kind (message<->enum), regenerate all dependent descriptors.
- Cross-check Type against the resolved symbol kind during descriptor import.
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
- "TypeName" is not an enum type.
- Field with primitive type has type_name.
- Expected an object
- Unsupported JSON token type
- Unsupported conversion from JSON number for field type
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)