XINCGer/Unity3DTraining · error · DescriptorValidationException

" " is already defined in file " ".

Error message

"{fullName}" is already defined in file "{old.File.Name}".

What it means

DescriptorPool.AddSymbol throws DescriptorValidationException when a message, enum, service, or enum value descriptor is registered under a fully-qualified name that already exists in the pool. Protobuf requires every fully-qualified symbol within a file's set of descriptors to be unique; duplicate registration is a validation error.

Solutions

  1. Find the duplicate fully-qualified name in the .proto files and rename one of the conflicting declarations.
  2. Ensure the same .proto file is not registered twice in one descriptor pool (deduplicate your FileDescriptorSet).
  3. Rename enum values that collide with sibling types, or wrap the enum in a message to scope its values (proto3 style).
  4. Regenerate all descriptors from the corrected .proto sources.

Example fix

// before
package myapp;
message User {}
message User {} // duplicate
// after
package myapp;
message User {}
message UserProfile {} // unique name
Defensive patterns

Strategy: validation

Validate before calling

// Deduplicate file names before building:
var uniqueDeps = dependencies
    .GroupBy(d => d.Name)
    .Select(g => g.First())
    .ToList();

Try / catch

try
{
    var fd = FileDescriptor.BuildFromByteString(bytes, dependencies);
}
catch (DescriptorValidationException ex) when (ex.Message.Contains("is already defined in file"))
{
    // identify duplicate symbol from ex.Message and drop/rename the duplicate
}

Prevention

When it happens

Trigger: Building a FileDescriptor (BuildFromByteString, FromGeneratedCode, or building dependent descriptors) where two declarations resolve to the same fully-qualified name — e.g. two messages with the same name in the same package, or an enum value colliding with a sibling type (enum values share the enclosing scope's namespace in proto2 semantics).

Common situations: Duplicate message names across .proto files sharing one package; an enum value name equal to another type name in the same scope (proto2 C++ scoping rules); concatenating multiple FileDescriptorSets that both contain the same file; a build pipeline shipping stale and new generated descriptors together.

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


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

Appendix: source

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

                int dotPos = fullName.LastIndexOf('.');
                string message;
                if (descriptor.File == old.File)
                {
                    if (dotPos == -1)
                    {
                        message = "\"" + fullName + "\" is already defined.";
                    }
                    else
                    {
                        message = "\"" + fullName.Substring(dotPos + 1) + "\" is already defined in \"" +
                                  fullName.Substring(0, dotPos) + "\".";
                    }
                }
                else
                {
                    message = "\"" + fullName + "\" is already defined in file \"" + old.File.Name + "\".";
                }
                throw new DescriptorValidationException(descriptor, message);
            }
            descriptorsByName[fullName] = descriptor;
        }

        private static readonly Regex ValidationRegex = new Regex("^[_A-Za-z][_A-Za-z0-9]*$",
                                                                  FrameworkPortability.CompiledRegexWhereAvailable);

        /// <summary>
        /// Verifies that the descriptor's name is valid (i.e. it contains
        /// only letters, digits and underscores, and does not start with a digit).
        /// </summary>
        /// <param name="descriptor"></param>
        private static void ValidateSymbolName(IDescriptor descriptor)
        {
            if (descriptor.Name == "")
            {
                throw new DescriptorValidationException(descriptor, "Missing name.");
            }

View on GitHub (pinned to 016f98412e)