XINCGer/Unity3DTraining · error · DescriptorValidationException

" " is not defined.

Error message

"{name}" is not defined.

What it means

DescriptorPool.LookupSymbol throws DescriptorValidationException when resolving a type name referenced from a proto declaration (e.g. a field's type_name or a method's input/output type) fails. The name is looked up with protobuf's scope resolution rules (relative to the referencing descriptor's scope, then the root), and if nothing matches, the reference is reported as undefined relative to the containing descriptor.

Solutions

  1. Ensure all dependency .proto files of the failing file are built into the same descriptor pool before it.
  2. Fix the type reference: use the correct fully-qualified name with a leading dot (e.g. ".myapp.Message") or correct relative name.
  3. Check for typos/renames: search your .proto sources for the referenced name and update the definition or reference.
  4. When loading dynamically, build the full transitive dependency set (protoc --include_imports) instead of individual files.

Example fix

// before
new FieldDescriptorProto { Name = "owner", TypeName = "User", ... } // User not in pool
// after
new FieldDescriptorProto { Name = "owner", TypeName = ".myapp.User", ... } // correct FQN, User file loaded first
Defensive patterns

Strategy: validation

Validate before calling

// Ensure every imported/dependent file is passed as a dependency before building:
var byName = allFiles.ToDictionary(f => f.Name);
var deps = fileProto.Dependency
    .Select(d => byName.TryGetValue(d, out var fd) ? fd : throw new InvalidOperationException($"Missing dependency {d}"))
    .ToList();

Try / catch

try
{
    var fd = FileDescriptor.BuildFromByteString(bytes, dependencies);
}
catch (DescriptorValidationException ex) when (ex.Message.Contains("is not defined."))
{
    // load missing dependency files or fix the type_name reference
}

Prevention

When it happens

Trigger: Building a FileDescriptor where a field's type_name (e.g. ".myapp.MissingMessage" or a relative "MissingMessage") does not match any message/enum registered in the pool — a typo in a type reference, a referenced type defined in a file that was not added to the pool, or a type removed by refactoring while references remained.

Common situations: Loading a subset of a FileDescriptorSet (missing dependency files); renaming a message in one .proto without updating references; hand-building descriptors with type_name strings that don't match actual declarations; relying on relative names without the leading dot when the type lives in a different package.

Understand the failure class

Background: 'Could not be found', 'does not exist', 'not found in database': the resource-not-found family when an ID, slug, key, or URI lookup comes back empty — this error's family across 20 libraries.

Related errors


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

Appendix: source

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

                                // We only found the first part of the symbol.  Now look for
                                // the whole thing.  If this fails, we *don't* want to keep
                                // searching parent scopes.
                                scopeToTry.Length = dotpos + 1;
                                scopeToTry.Append(name);
                                result = FindSymbol<IDescriptor>(scopeToTry.ToString());
                            }
                            break;
                        }

                        // Not found.  Remove the name so we can try again.
                        scopeToTry.Length = dotpos;
                    }
                }
            }

            if (result == null)
            {
                throw new DescriptorValidationException(relativeTo, "\"" + name + "\" is not defined.");
            }
            else
            {
                return result;
            }
        }

        /// <summary>
        /// Struct used to hold the keys for the fieldByNumber table.
        /// </summary>
        private struct DescriptorIntPair : IEquatable<DescriptorIntPair>
        {
            private readonly int number;
            private readonly IDescriptor descriptor;

            internal DescriptorIntPair(IDescriptor descriptor, int number)
            {
                this.number = number;

View on GitHub (pinned to 016f98412e)