{"record":{"id":"e851ab6b8aa43b22","repo":"XINCGer/Unity3DTraining","slug":"type-registry-has-no-descriptor-for-type-name-e851ab","errorCode":null,"errorMessage":"Type registry has no descriptor for type name '","messagePattern":"Type registry has no descriptor for type name '","errorType":"exception","errorClass":"InvalidOperationException","httpStatus":null,"severity":"error","filePath":"NetWorkAndResources/Socket_Protobuff/Assets/Plugins/Google.Protobuf/JsonParser.cs","lineNumber":522,"sourceCode":"                if (tokenizer.ObjectDepth < typeUrlObjectDepth)\n                {\n                    throw new InvalidProtocolBufferException(\"Any message with no @type\");\n                }\n            }\n\n            // Don't add the @type property or its value to the recorded token list\n            token = tokenizer.Next();\n            if (token.Type != JsonToken.TokenType.StringValue)\n            {\n                throw new InvalidProtocolBufferException(\"Expected string value for Any.@type\");\n            }\n            string typeUrl = token.StringValue;\n            string typeName = Any.GetTypeName(typeUrl);\n\n            MessageDescriptor descriptor = settings.TypeRegistry.Find(typeName);\n            if (descriptor == null)\n            {\n                throw new InvalidOperationException(\"Type registry has no descriptor for type name '\" + typeName + \"'\");\n            }\n\n            // Now replay the token stream we've already read and anything that remains of the object, just parsing it\n            // as normal. Our original tokenizer should end up at the end of the object.\n            var replay = JsonTokenizer.FromReplayedTokens(tokens, tokenizer);\n            var body = descriptor.Parser.CreateTemplate();\n            if (descriptor.IsWellKnownType)\n            {\n                MergeWellKnownTypeAnyBody(body, replay);\n            }\n            else\n            {\n                Merge(body, replay);\n            }\n            var data = body.ToByteString();\n\n            // Now that we have the message data, we can pack it into an Any (the message received as a parameter).\n            message.Descriptor.Fields[Any.TypeUrlFieldNumber].Accessor.SetValue(message, typeUrl);","sourceCodeStart":504,"sourceCodeEnd":540,"githubUrl":"https://github.com/XINCGer/Unity3DTraining/blob/016f98412ea5e11756b286736f479b66ab6216d5/NetWorkAndResources/Socket_Protobuff/Assets/Plugins/Google.Protobuf/JsonParser.cs#L504-L540","documentation":"Google.Protobuf's JsonParser, when parsing an google.protobuf.Any field, extracts the type name from the '@type' URL and looks it up in the parser's TypeRegistry. If the registry cannot resolve that type name, this InvalidOperationException is thrown because the parser cannot create a message template to merge the Any body into.","triggerScenarios":"Parsing JSON containing an Any field whose @type URL names a message type that was never registered via JsonParser.WithTypeRegistry(...).With(TypeRegistry.FromMessages(...)) — e.g. parsing output from a server that used types not present or not registered on the client.","commonSituations":"Client/server use different .proto type sets; developer forgets to add custom message types to the TypeRegistry when deserializing Any; type name mismatch between producer and consumer (different package names).","solutions":["Register the missing type: JsonParser.Default.WithTypeRegistry(TypeRegistry.FromMessages(typeof(MyMessage))) and parse with that parser instance.","Verify the @type URL's type name matches the registered message's full proto name (package.MessageName).","If the Any payload is unknown to the client, parse the field as a raw Any (it stays unparsed) instead of requesting unpacking, and inspect TypeUrl manually."],"exampleFix":"// before\nvar msg = JsonParser.Default.Parse<Wrapper>(json);\n// after\nvar registry = TypeRegistry.FromMessages(typeof(MyCustomMessage), typeof(AnotherMessage));\nvar parser = JsonParser.Default.WithTypeRegistry(registry);\nvar msg = parser.Parse<Wrapper>(json);","handlingStrategy":"try-catch","validationCode":"// Pre-check that every @type in the JSON is registered\nvar registered = TypeRegistry.FromMessages(typeof(MyMessage));\nforeach (Match m in Regex.Matches(json, '\"@type\"\\\\s*:\\\\s*\"([^\"]+)\"'))\n{\n    string typeName = Any.GetTypeName(m.Groups[1].Value);\n    if (registered.Find(typeName) == null) throw new Exception($\"Unregistered Any type: {typeName}\");\n}","typeGuard":"static bool IsAnyTypeRegistered(TypeRegistry registry, string json)\n{\n    var match = Regex.Match(json, '\"@type\"\\\\s*:\\\\s*\"([^\"]+)\"');\n    return match.Success && registry.Find(Any.GetTypeName(match.Groups[1].Value)) != null;\n}","tryCatchPattern":"try\n{\n    var msg = parser.Parse<T>(json);\n}\ncatch (InvalidOperationException ex) when (ex.Message.StartsWith(\"Type registry has no descriptor\"))\n{\n    // fall back to a registry that includes the missing type, or keep Any raw\n    logger.LogWarning(ex, \"Unknown Any type in payload\");\n}","preventionTips":["Always build parsers via JsonParser.Default.WithTypeRegistry(TypeRegistry.FromMessages(...all shared types...))","Keep the client's type registry in sync with every message type servers may embed in Any","Log Any.TypeUrl values in integration tests to catch registry gaps early"],"tags":["protobuf","json-parsing","any-type","type-registry"],"backgroundTag":"protobuf-unmarshal-failed","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"}