XINCGer/Unity3DTraining · error · DescriptorValidationException

"TypeName" is not a type.

Error message

"TypeName" is not a type.

What it means

During CrossLink, a field that uses type_name (rather than an inline type) must resolve, via the descriptor pool, to either a MessageDescriptor or an EnumDescriptor. If the resolved symbol is neither, the field's TypeName points at something that exists but is not a type (e.g. a service or another field), and DescriptorValidationException is thrown.

Solutions

  1. Fix Proto.TypeName to the correct fully-qualified message or enum name and regenerate/rebuild the descriptor.
  2. Verify with DescriptorPool.LookupSymbol / FindName that the name resolves to a MessageDescriptor or EnumDescriptor before building.
  3. Regenerate descriptors from the .proto source with protoc instead of editing serialized descriptor bytes.

Example fix

// before
typeName = "MyApp.Services.MyService" // resolves to a service, not a type
// after
typeName = "MyApp.Messages.MyMessage"
Defensive patterns

Strategy: validation

Validate before calling

var sym = pool.LookupSymbol(field.Proto.TypeName, field);
if (!(sym is MessageDescriptor) && !(sym is EnumDescriptor))
    throw new InvalidDataException(field.Proto.TypeName + " is not a message or enum type");

Type guard

bool IsNamedType(string typeName, DescriptorPool pool, out object sym)
{ sym = pool.FindSymbol(typeName); return sym is MessageDescriptor || sym is EnumDescriptor; }

Try / catch

try { descriptor = FileDescriptor.BuildFromByteStrings(data); }
catch (DescriptorValidationException ex)
{ log.LogError(ex, "type_name does not resolve to a type: " + ex.Message); }

Prevention

When it happens

Trigger: A FieldDescriptorProto whose Type is TYPE_MESSAGE/TYPE_ENUM but whose TypeName resolves to a non-type symbol in the pool — e.g. TypeName pointing at a service, method, or field; misspelled or wrongly-scoped fully-qualified type names in hand-built protos.

Common situations: Hand-assembling descriptors with wrong fully-qualified names; renaming/merging protos so a type_name now collides with a non-type symbol; stale generated descriptor sets after refactors.

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/b03efeb85cfd053c. Report an issue: GitHub.

Appendix: source

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

            if (Proto.TypeName != "")
            {
                IDescriptor typeDescriptor =
                    File.DescriptorPool.LookupSymbol(Proto.TypeName, this);

                if (Proto.Type != 0)
                {
                    // Choose field type based on symbol.
                    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)
                {

View on GitHub (pinned to 016f98412e)