{"record":{"id":"e5afd77097c744ac","repo":"XINCGer/Unity3DTraining","slug":"descriptor-name-is-not-a-valid-identifier","errorCode":null,"errorMessage":"\"{descriptor.Name}\" is not a valid identifier.","messagePattern":"\"(.+?)\" is not a valid identifier\\.","errorType":"validation","errorClass":"DescriptorValidationException","httpStatus":null,"severity":"error","filePath":"NetWorkAndResources/Socket_Protobuff/Assets/Plugins/Google.Protobuf/Reflection/DescriptorPool.cs","lineNumber":200,"sourceCode":"        }\n\n        private static readonly Regex ValidationRegex = new Regex(\"^[_A-Za-z][_A-Za-z0-9]*$\",\n                                                                  FrameworkPortability.CompiledRegexWhereAvailable);\n\n        /// <summary>\n        /// Verifies that the descriptor's name is valid (i.e. it contains\n        /// only letters, digits and underscores, and does not start with a digit).\n        /// </summary>\n        /// <param name=\"descriptor\"></param>\n        private static void ValidateSymbolName(IDescriptor descriptor)\n        {\n            if (descriptor.Name == \"\")\n            {\n                throw new DescriptorValidationException(descriptor, \"Missing name.\");\n            }\n            if (!ValidationRegex.IsMatch(descriptor.Name))\n            {\n                throw new DescriptorValidationException(descriptor,\n                                                        \"\\\"\" + descriptor.Name + \"\\\" is not a valid identifier.\");\n            }\n        }\n\n        /// <summary>\n        /// Returns the field with the given number in the given descriptor,\n        /// or null if it can't be found.\n        /// </summary>\n        internal FieldDescriptor FindFieldByNumber(MessageDescriptor messageDescriptor, int number)\n        {\n            FieldDescriptor ret;\n            fieldsByNumber.TryGetValue(new DescriptorIntPair(messageDescriptor, number), out ret);\n            return ret;\n        }\n\n        internal EnumValueDescriptor FindEnumValueByNumber(EnumDescriptor enumDescriptor, int number)\n        {\n            EnumValueDescriptor ret;","sourceCodeStart":182,"sourceCodeEnd":218,"githubUrl":"https://github.com/XINCGer/Unity3DTraining/blob/016f98412ea5e11756b286736f479b66ab6216d5/NetWorkAndResources/Socket_Protobuff/Assets/Plugins/Google.Protobuf/Reflection/DescriptorPool.cs#L182-L218","documentation":"DescriptorPool.ValidateSymbolName throws DescriptorValidationException when a descriptor's Name is non-empty but not a valid protobuf identifier. Valid names must match ^[_A-Za-z][_A-Za-z0-9]*$ — start with a letter or underscore, then only letters, digits, or underscores. Note that in practice protoc already rejects such names, so this usually indicates hand-built or tampered descriptors.","triggerScenarios":"Building descriptors from a FileDescriptorProto where a declaration's name starts with a digit (e.g. \"2fa\"), contains a hyphen or dot (\"my-field\", \"a.b\"), or contains whitespace — typically from programmatically constructed DescriptorProtos or dynamically generated names derived from unvalidated input.","commonSituations":"Generating message/field names from external data (table names, HTTP header names with hyphens, JSON keys with special characters) without sanitizing; post-processing descriptor sets with scripts that mangle names; dynamic schema builders allowing arbitrary strings.","solutions":["Sanitize generated names: replace invalid characters with '_' and prefix with a letter if the name starts with a digit.","Validate names against ^[_A-Za-z][_A-Za-z0-9]*$ before adding them to a DescriptorProto/FieldDescriptorProto.","Fix the source .proto file if it (impossibly, via old tooling) contains an invalid identifier, then re-run protoc.","If names come from user input, map them to a whitelist of valid identifiers."],"exampleFix":"// before\nvar field = new FieldDescriptorProto { Name = \"first-name\", Number = 1, Type = FieldDescriptorProto.Types.Type.String };\n// after\nvar field = new FieldDescriptorProto { Name = \"first_name\", Number = 1, Type = FieldDescriptorProto.Types.Type.String };","handlingStrategy":"validation","validationCode":"static readonly Regex Ident = new Regex(\"^[_A-Za-z][_A-Za-z0-9]*$\");\nstatic string SanitizeName(string raw)\n{\n    var s = new string(raw.Select(c => char.IsLetterOrDigit(c) || c == '_' ? c : '_').ToArray());\n    if (s.Length == 0 || char.IsDigit(s[0])) s = \"_\" + s;\n    return s;\n}\n// apply: field.Name = SanitizeName(externalName);","typeGuard":"bool IsValidIdentifier(string name) =>\n    !string.IsNullOrEmpty(name) && Regex.IsMatch(name, \"^[_A-Za-z][_A-Za-z0-9]*$\");","tryCatchPattern":"try\n{\n    var fd = FileDescriptor.BuildFromByteString(bytes, dependencies);\n}\ncatch (DescriptorValidationException ex) when (ex.Message.Contains(\"is not a valid identifier\"))\n{\n    // sanitize the offending declaration name and rebuild\n}","preventionTips":["Sanitize any externally derived names before using them as proto identifiers","Validate with ^[_A-Za-z][_A-Za-z0-9]*$ at descriptor-construction time","Lint generated descriptors in CI"],"tags":["protobuf","descriptor","identifier","validation","csharp"],"backgroundTag":"invalid-identifier-format","analyzedSha":"016f98412ea5e11756b286736f479b66ab6216d5","analyzedAt":"2026-09-12T01:08:58.711Z","contentChangedAt":"2026-09-12T01:08:58.711Z","schemaVersion":2},"datasetVersion":"2026-09-16T09:17:16.951Z"}