{"record":{"id":"b9127eb7bdc923b7","repo":"XINCGer/Unity3DTraining","slug":"invalid-duration-value-token-stringvalue","errorCode":null,"errorMessage":"Invalid Duration value: {token.StringValue}","messagePattern":"Invalid Duration value: (.+?)","errorType":"exception","errorClass":"InvalidProtocolBufferException","httpStatus":null,"severity":"error","filePath":"NetWorkAndResources/Socket_Protobuff/Assets/Plugins/Google.Protobuf/JsonParser.cs","lineNumber":868,"sourceCode":"                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            {\n                long seconds = long.Parse(secondsText, CultureInfo.InvariantCulture) * multiplier;\n                int nanos = 0;\n                if (subseconds != \"\")\n                {\n                    // This should always work, as we've got 1-9 digits.","sourceCodeStart":850,"sourceCodeEnd":886,"githubUrl":"https://github.com/XINCGer/Unity3DTraining/blob/016f98412ea5e11756b286736f479b66ab6216d5/NetWorkAndResources/Socket_Protobuff/Assets/Plugins/Google.Protobuf/JsonParser.cs#L850-L886","documentation":"After the token is confirmed a string, MergeDuration applies DurationRegex; strings that do not match the canonical Duration JSON grammar (sign, integer seconds, optional fractional part, mandatory 's' suffix) throw 'Invalid Duration value: ...'.","triggerScenarios":"Parsing values like \"5\" (no s), \"5 sec\", \"PT5S\" (ISO 8601), \"1h30m\", \"\", or \".5s\" via JsonParser for a Duration field — anything not matching ^-?[0-9]+(\\.[0-9]{1,9})?s$.","commonSituations":"Using ISO 8601 durations (PT5S) from other systems; omitting the trailing 's'; passing TimeSpan.ToString() output that lacks the 's'; locale-formatted numbers with commas.","solutions":["Format the duration as seconds with optional fraction and trailing 's': \"5s\", \"-1.5s\", \"0.000000001s\".","Convert TimeSpan with $\"{(long)ts.TotalSeconds}.{ts.Milliseconds...}s\" or similar canonical form.","Catch InvalidProtocolBufferException and normalize/repair the string before retrying.","Validate with regex ^-?\\d+(\\.\\d{1,9})?s$ before calling the parser."],"exampleFix":"// before\nvar d = parser.Parse<Duration>(\"\\\"PT5S\\\"\");\n// after\nvar d = parser.Parse<Duration>(\"\\\"5s\\\"\");","handlingStrategy":"validation","validationCode":"static readonly System.Text.RegularExpressions.Regex DurationRegex =\n    new(@\"^-?\\d+(\\.\\d{1,9})?s$\");\nbool IsCanonicalDuration(string s) => DurationRegex.IsMatch(s);","typeGuard":"bool IsValidDurationString(string s) => DurationRegex.IsMatch(s);","tryCatchPattern":"try { var d = JsonParser.Default.Parse<Duration>(jsonValue); }\ncatch (InvalidProtocolBufferException ex) when (ex.Message.StartsWith(\"Invalid Duration\"))\n{ log.Warn($\"Bad duration '{raw}'\"); throw new ArgumentException(\"duration must look like \\\"3.5s\\\"\", ex); }","preventionTips":["Always include the trailing 's'","Don't use ISO 8601 (PT5S) or TimeSpan.ToString() output directly","Convert numeric seconds with $\"{seconds}s\"","Pre-validate with a regex before parsing"],"tags":["protobuf","json-parsing","duration","regex"],"backgroundTag":"invalid-duration-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"}