{"record":{"id":"a2e574a1a72c96e4","repo":"kataras/iris","slug":"invalid-duration-format-expected-hours-minutes-se","errorCode":null,"errorMessage":"invalid duration format: expected hours:minutes:seconds (e.g. 01:05:00) but got: %s","messagePattern":"invalid duration format: expected hours:minutes:seconds \\(e\\.g\\. 01:05:00\\) but got: (.+?)","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"x/jsonx/time_notation.go","lineNumber":30,"sourceCode":"\t\"time\"\n)\n\n// TimeNotationDuration is a JSON representation of the standard Duration type in 00:00:00 (hour, minute seconds).\ntype TimeNotationDuration time.Duration\n\nfunc fmtDuration(d time.Duration) string {\n\td = d.Round(time.Minute)\n\th := d / time.Hour\n\td -= h * time.Hour\n\tm := d / time.Minute\n\treturn fmt.Sprintf(\"%02d:%02d:00\", h, m) // Manos doesn't care about the seconds.\n}\n\n// ParseTimeNotationDuration parses a string to a time notation duration (00:00:00) hours:minutes:seconds.\nfunc ParseTimeNotationDuration(s string) (TimeNotationDuration, error) {\n\tentries := strings.SplitN(s, \":\", 3)\n\tif len(entries) < 3 {\n\t\treturn TimeNotationDuration(0), fmt.Errorf(\"invalid duration format: expected hours:minutes:seconds (e.g. 01:05:00) but got: %s\", s)\n\t}\n\n\thours, err := strconv.Atoi(entries[0])\n\tif err != nil {\n\t\treturn TimeNotationDuration(0), err\n\t}\n\tminutes, err := strconv.Atoi(entries[1])\n\tif err != nil {\n\t\treturn TimeNotationDuration(0), err\n\t}\n\n\t// remove any .0000\n\tsecondsStr := strings.TrimSuffix(entries[2], \".000000\")\n\tseconds, err := strconv.Atoi(secondsStr)\n\tif err != nil {\n\t\treturn TimeNotationDuration(0), err\n\t}\n","sourceCodeStart":12,"sourceCodeEnd":48,"githubUrl":"https://github.com/kataras/iris/blob/7bedaf55a0b64bbb2248a5845a2c60d81a30996a/x/jsonx/time_notation.go#L12-L48","documentation":"ParseTimeNotationDuration splits the input on ':' and requires exactly three parts (hours:minutes:seconds). Strings with fewer than three colon-separated parts — e.g. \"10:00\", \"90m\", \"\" — fail immediately with \"invalid duration format: expected hours:minutes:seconds (e.g. 01:05:00) but got: %s\".","triggerScenarios":"Calling jsonx.ParseTimeNotationDuration directly, or via TimeNotationDuration.UnmarshalJSON with a short string, or via KitchenTime.Scan receiving a string TIME value with only h:mm (two parts).","commonSituations":"DB TIME values rendered as \"10:00\" (HH:MM); user-supplied durations like \"1:30\" intended as 1h30m; config files storing Go duration strings (\"1h30m\").","solutions":["Pad the value to three parts before parsing: \"10:00\" -> \"10:00:00\".","If the source is Go time.Duration text, convert with time.ParseDuration and TimeNotationDuration.Set instead.","On Postgres, cast TIME columns with to_char(col, 'HH24:MI:SS') so three parts are always present."],"exampleFix":"// before\njsonx.ParseTimeNotationDuration(\"10:00\") // error\n// after\njsonx.ParseTimeNotationDuration(\"10:00:00\")","handlingStrategy":"validation","validationCode":"func isTimeNotation(s string) bool {\n\tparts := strings.SplitN(s, \":\", 3)\n\tif len(parts) != 3 { return false }\n\tfor _, p := range parts {\n\t\tif _, err := strconv.Atoi(p); err != nil { return false }\n\t}\n\treturn true\n}","typeGuard":"func normalizeTimeNotation(s string) string {\n\tparts := strings.Split(s, \":\")\n\tfor len(parts) < 3 {\n\t\tparts = append(parts, \"00\")\n\t}\n\treturn strings.Join(parts[:3], \":\")\n}","tryCatchPattern":"d, err := jsonx.ParseTimeNotationDuration(s)\nif err != nil {\n\tif strings.HasPrefix(err.Error(), \"invalid duration format\") {\n\t\td, err = jsonx.ParseTimeNotationDuration(normalizeTimeNotation(s))\n\t}\n\tif err != nil { return err }\n}","preventionTips":["Always store/pad durations as HH:MM:SS","Cast Postgres TIME with to_char(col,'HH24:MI:SS')","Normalize HH:MM inputs by appending ':00' before parsing"],"tags":["go","json","duration","time-parsing"],"backgroundTag":"invalid-duration-format","analyzedSha":"7bedaf55a0b64bbb2248a5845a2c60d81a30996a","analyzedAt":"2026-08-30T20:38:16.250Z","schemaVersion":2},"datasetVersion":"2026-08-30T23:17:21.991Z"}