{"record":{"id":"e6550db94230a48f","repo":"XINCGer/Unity3DTraining","slug":"expected-string-value-for-duration","errorCode":null,"errorMessage":"Expected string value for Duration","messagePattern":"Expected string value for Duration","errorType":"exception","errorClass":"InvalidProtocolBufferException","httpStatus":null,"severity":"error","filePath":"NetWorkAndResources/Socket_Protobuff/Assets/Plugins/Google.Protobuf/JsonParser.cs","lineNumber":863,"sourceCode":"                    if (timestamp.Seconds < Timestamp.UnixSecondsAtBclMinValue || timestamp.Seconds > Timestamp.UnixSecondsAtBclMaxValue)\n                    {\n                        throw new InvalidProtocolBufferException(\"Invalid Timestamp value: \" + token.StringValue);\n                    }\n                }\n                message.Descriptor.Fields[Timestamp.SecondsFieldNumber].Accessor.SetValue(message, timestamp.Seconds);\n                message.Descriptor.Fields[Timestamp.NanosFieldNumber].Accessor.SetValue(message, timestamp.Nanos);\n            }\n            catch (FormatException)\n            {\n                throw new InvalidProtocolBufferException(\"Invalid Timestamp value: \" + token.StringValue);\n            }\n        }\n\n        private static void MergeDuration(IMessage message, JsonToken token)\n        {\n            if (token.Type != JsonToken.TokenType.StringValue)\n            {\n                throw new InvalidProtocolBufferException(\"Expected string value for Duration\");\n            }\n            var match = DurationRegex.Match(token.StringValue);\n            if (!match.Success)\n            {\n                throw new InvalidProtocolBufferException(\"Invalid Duration value: \" + token.StringValue);\n            }\n            var sign = match.Groups[\"sign\"].Value;\n            var secondsText = match.Groups[\"int\"].Value;\n            // Prohibit leading insignficant zeroes\n            if (secondsText[0] == '0' && secondsText.Length > 1)\n            {\n                throw new InvalidProtocolBufferException(\"Invalid Duration value: \" + token.StringValue);\n            }\n            var subseconds = match.Groups[\"subseconds\"].Value;\n            var multiplier = sign == \"-\" ? -1 : 1;\n\n            try\n            {","sourceCodeStart":845,"sourceCodeEnd":881,"githubUrl":"https://github.com/XINCGer/Unity3DTraining/blob/016f98412ea5e11756b286736f479b66ab6216d5/NetWorkAndResources/Socket_Protobuff/Assets/Plugins/Google.Protobuf/JsonParser.cs#L845-L881","documentation":"MergeDuration requires the Duration well-known type to appear in JSON as a string (e.g. \"3.5s\"). If the JSON token for a google.protobuf.Duration field is not a string value (number, object, bool, null), the parser throws 'Expected string value for Duration'.","triggerScenarios":"Parsing JSON where a Duration field is given as a number ({\"duration\": 5}), an object ({\"duration\": {\"seconds\": 5}}), or null instead of the canonical string form ({\"duration\": \"5s\"}) via JsonParser.Parse<T>.","commonSituations":"JSON hand-written by developers assuming seconds-as-number; JSON from other serializers that map Duration to a numeric or struct; clients not following the protobuf JSON mapping spec.","solutions":["Encode the Duration as a string with an 's' suffix: \"5s\", \"3.000000001s\".","Fix the producing side to follow the canonical protobuf JSON mapping for Duration.","Catch InvalidProtocolBufferException and convert numeric inputs to the string form before parsing.","If you control the schema, consider using int64 seconds fields instead of Duration when interop matters."],"exampleFix":"// before\nstring json = \"{\\\"duration\\\": 5}\";\n// after\nstring json = \"{\\\"duration\\\": \\\"5s\\\"}\";","handlingStrategy":"type-guard","validationCode":"bool IsDurationStringToken(object token) => token is string;\n// caller-side: ensure the JSON field value is a string before parsing","typeGuard":"bool IsJsonString(object v) => v is string s && s != null;\n// or for JSON: if (field.Value.Type != JTokenType.String) reject;","tryCatchPattern":"try { var d = JsonParser.Default.Parse<Duration>(json); }\ncatch (InvalidProtocolBufferException ex) when (ex.Message.StartsWith(\"Expected string value for Duration\"))\n{ log.Warn(\"Duration field must be a string like \\\"5s\\\"\"); throw; }","preventionTips":["Always serialize Duration as \"<seconds>s\" string per the protobuf JSON mapping","Never map Duration to a raw number or nested object","Document the canonical form for API consumers","Add schema validation that Duration fields are strings"],"tags":["protobuf","json-parsing","duration","type-mismatch"],"backgroundTag":"type-mismatch","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"}