{"record":{"id":"3ccbd04b6beb4555","repo":"XINCGer/Unity3DTraining","slug":"expected-string-value-for-any-type","errorCode":null,"errorMessage":"Expected string value for Any.@type","messagePattern":"Expected string value for Any\\.@type","errorType":"validation","errorClass":"InvalidProtocolBufferException","httpStatus":null,"severity":"error","filePath":"NetWorkAndResources/Socket_Protobuff/Assets/Plugins/Google.Protobuf/JsonParser.cs","lineNumber":514,"sourceCode":"            // for *this* Any.\n            while (token.Type != JsonToken.TokenType.Name ||\n                token.StringValue != JsonFormatter.AnyTypeUrlField ||\n                tokenizer.ObjectDepth != typeUrlObjectDepth)\n            {\n                tokens.Add(token);\n                token = tokenizer.Next();\n\n                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            }","sourceCodeStart":496,"sourceCodeEnd":532,"githubUrl":"https://github.com/XINCGer/Unity3DTraining/blob/016f98412ea5e11756b286736f479b66ab6216d5/NetWorkAndResources/Socket_Protobuff/Assets/Plugins/Google.Protobuf/JsonParser.cs#L496-L532","documentation":"Once MergeAny finds the \"@type\" property name, it expects the next token to be the type URL as a JSON string. If the value of @type is not a StringValue token (e.g. an object, array, number, or null), it throws this InvalidProtocolBufferException. The parser then resolves the type name via the TypeRegistry.","triggerScenarios":"Parsing an Any field where @type has a non-string value, e.g. {\"@type\": 123}, {\"@type\": null}, or {\"@type\": {\"url\": \"...\"}}; also payloads where @type's value got wrapped or array-encoded.","commonSituations":"Templating bugs that interpolate the type URL incorrectly; serializers emitting type information as a structured object instead of a string; copy-paste mistakes where the @type value was quoted twice or object-encoded by middleware.","solutions":["Make @type a plain JSON string: \"@type\": \"type.googleapis.com/pkg.Type\".","Check middleware/serialization layers that may re-encode the @type value into an object or array.","Validate at ingress that every Any object has @type as a string starting with the expected type URL prefix.","After the string value, ensure settings.TypeRegistry contains the type name — a missing registration leads to the subsequent descriptor==null failure path."],"exampleFix":"// before: non-string @type\n{\"detail\": {\"@type\": {\"url\": \"type.googleapis.com/foo.Bar\"}}}\n\n// after\n{\"detail\": {\"@type\": \"type.googleapis.com/foo.Bar\", \"id\": 42}}","handlingStrategy":"validation","validationCode":"// @type value must be a plain string\nfunction validateTypeUrl(obj) {\n  if (typeof obj?.['@type'] !== 'string') throw new Error('@type must be a string like type.googleapis.com/pkg.Type');\n}","typeGuard":"function isStringTypeUrl(v) { return v !== null && typeof v === 'object' && typeof v['@type'] === 'string' && v['@type'].startsWith('type.googleapis.com/'); }","tryCatchPattern":"try { var msg = JsonParser.Default.Parse<T>(json); }\ncatch (InvalidProtocolBufferException ex) when (ex.Message == \"Expected string value for Any.@type\") { /* reject: @type must be a plain string */ }","preventionTips":["Emit @type as a plain quoted JSON string, never as an object or number","Ensure middleware does not re-encode @type values","Register the target types with settings.TypeRegistry so resolution succeeds after @type is parsed"],"tags":["protobuf","json-parsing","any","type-url"],"backgroundTag":"invalid-argument-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"}