XINCGer/Unity3DTraining · error · DescriptorValidationException
" " is already defined (as something other than a package)…
Error message
"{name}" is already defined (as something other than a package) in file "{old.File.Name}". What it means
DescriptorPool.AddPackage throws DescriptorValidationException when building a FileDescriptor if the package name being registered collides with an existing symbol (message, enum, service, field, etc.) of the same fully-qualified name in the pool. A name can only refer to a package if nothing else has already claimed it. This mirrors protobuf's C++ descriptor validation rules.
Solutions
- Rename the conflicting declaration: either the package in one .proto file or the message/enum/service with the same fully-qualified name.
- Check every loaded file in the pool for a type whose fully-qualified name equals the package name in the failing file.
- Regenerate code after renaming so descriptors are consistent.
- If files are loaded dynamically, load the package-declaring file first or into a separate pool to avoid cross-file collisions.
Example fix
// before (file A)
message foo { ... } // fully-qualified: foo
// file B
package foo.bar; // collides with message foo
// after
message FooMsg { ... } // no collision with package foo Defensive patterns
Strategy: validation
Validate before calling
// Before building a FileDescriptor, collect every type FQN already in the pool // and check the new file's package against them: bool collides = existingTypeFqns.Contains(newFileProto.Package);
Try / catch
try
{
var fd = FileDescriptor.BuildFromByteString(bytes, dependencies);
}
catch (DescriptorValidationException ex) when (ex.Message.Contains("as something other than a package"))
{
// surface the conflicting file/name to schema maintainers
} Prevention
- Never name packages the same as any message/enum/service
- Keep a registry of fully-qualified names across all .proto files in the repo and lint for collisions
- Load file sets together and version them as one unit
When it happens
Trigger: Calling FileDescriptor.BuildFromByteString/FromGeneratedCode for a .proto file whose 'package' declaration has the same fully-qualified name as a message, enum, or service already registered in the same descriptor pool — e.g. package foo.bar while a message foo.bar already exists from a previously loaded file.
Common situations: Merging multiple .proto files into one pool where one file's package path coincidentally matches another file's message name; renaming/moving declarations so a package path now shadows an existing type; generated-code registration order issues after schema refactoring.
Understand the failure class
Background: Schema validation failed / invalid input schema: payload rejected because its shape doesn't match the expected schema — this error's family across 28 libraries.
Related errors
- " " is already defined in file " ".
- Missing name.
- " " is not a valid identifier.
- Field number has already been used in " " by field " ".
- " " is not defined.
AI-assisted analysis of XINCGer/Unity3DTraining@016f98412e (2026-09-12).
Data as JSON: /api/errors/89e76d4166b6c48f.
Report an issue: GitHub.
Appendix: source
Thrown at NetWorkAndResources/Socket_Protobuff/Assets/Plugins/Google.Protobuf/Reflection/DescriptorPool.cs:139
{
int dotpos = fullName.LastIndexOf('.');
String name;
if (dotpos != -1)
{
AddPackage(fullName.Substring(0, dotpos), file);
name = fullName.Substring(dotpos + 1);
}
else
{
name = fullName;
}
IDescriptor old;
if (descriptorsByName.TryGetValue(fullName, out old))
{
if (!(old is PackageDescriptor))
{
throw new DescriptorValidationException(file,
"\"" + name +
"\" is already defined (as something other than a " +
"package) in file \"" + old.File.Name + "\".");
}
}
descriptorsByName[fullName] = new PackageDescriptor(name, fullName, file);
}
/// <summary>
/// Adds a symbol to the symbol table.
/// </summary>
/// <exception cref="DescriptorValidationException">The symbol already existed
/// in the symbol table.</exception>
internal void AddSymbol(IDescriptor descriptor)
{
ValidateSymbolName(descriptor);
String fullName = descriptor.FullName;
View on GitHub (pinned to 016f98412e)