{"record":{"id":"0f858bb0a880f6f8","repo":"kataras/iris","slug":"invalid-offset-format-s","errorCode":null,"errorMessage":"invalid offset format: %s","messagePattern":"invalid offset format: (.+?)","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"x/jsonx/iso8601.go","lineNumber":232,"sourceCode":"\n\treturn secondsEastUTC, nil\n}\n\nfunc isUnconventionalOffset(offset string) bool {\n\tparts := strings.Split(offset, \":\")\n\treturn len(parts) == 3\n}\n\nfunc adjustForUnconventionalOffset(t time.Time, offset string) (time.Time, error) {\n\tsign := 1\n\tif offset[0] == '-' {\n\t\tsign = -1\n\t}\n\toffset = offset[1:]\n\n\toffsetParts := strings.Split(offset, \":\")\n\tif len(offsetParts) != 3 {\n\t\treturn time.Time{}, fmt.Errorf(\"invalid offset format: %s\", offset)\n\t}\n\n\thours, err := strconv.Atoi(offsetParts[0])\n\tif err != nil {\n\t\treturn time.Time{}, fmt.Errorf(\"error parsing offset hours: %s: %w\", offset, err)\n\t}\n\n\tif hours > 24 {\n\t\treturn time.Time{}, fmt.Errorf(\"invalid offset hours: %d: %s\", hours, offset)\n\t}\n\n\tminutes, err := strconv.Atoi(offsetParts[1])\n\tif err != nil {\n\t\treturn time.Time{}, fmt.Errorf(\"error parsing offset minutes: %s: %w\", offset, err)\n\t}\n\tif minutes > 60 {\n\t\treturn time.Time{}, fmt.Errorf(\"invalid offset minutes: %d: %s\", minutes, offset)\n\t}","sourceCodeStart":214,"sourceCodeEnd":250,"githubUrl":"https://github.com/kataras/iris/blob/7bedaf55a0b64bbb2248a5845a2c60d81a30996a/x/jsonx/iso8601.go#L214-L250","documentation":"ParseISO8601's adjustForUnconventionalOffset helper handles timezone offsets written as '+HH:MM:SS'. After stripping the sign it splits on ':' and requires exactly three numeric parts. This error is returned when the offset component of the timestamp does not contain three colon-separated fields, so the offset cannot be interpreted as hours:minutes:seconds.","triggerScenarios":"Calling ParseISO8601 (or ISO8601.UnmarshalJSON) with a timestamp whose UTC offset only becomes 'unconventional' during the split but lacks three parts — e.g. an offset like '+0300' or '+03' that reaches this code path with the wrong number of colon-delimited fields, or an empty offset string.","commonSituations":"Feeding timestamps from external systems that emit compact offsets (+0300) or hour-only offsets (+03); hand-crafted or copied date strings; upstream services changing timestamp serialization formats.","solutions":["Normalize the timestamp offset to extended form '+HH:MM:SS' (or a standard 'Z' / '+03:00' that the conventional parser accepts) before parsing.","Emit timestamps from the producer in RFC3339/ISO8601 standard form (e.g. time.Format(time.RFC3339)).","Sanitize at the boundary: convert '+0300' to '+03:00' with a small regex/string transform before calling ParseISO8601."],"exampleFix":"// before\nParseISO8601(\"2024-01-02T15:04:05+0300\") // invalid offset format\n// after\nParseISO8601(\"2024-01-02T15:04:05+03:00\")","handlingStrategy":"validation","validationCode":"var offsetRe = regexp.MustCompile(`^[+-]\\d{1,2}:\\d{2}:\\d{2}$`)\nfunc hasValidOffset(ts string) bool {\n\ti := strings.LastIndexAny(ts, \"+-\")\n\treturn i >= 0 && offsetRe.MatchString(ts[i:])\n}","typeGuard":"func isStandardRFC3339(s string) bool {\n\t_, err := time.Parse(time.RFC3339, s)\n\treturn err == nil\n}","tryCatchPattern":null,"preventionTips":["Always emit timestamps with time.Format(time.RFC3339) at the producer side.","Normalize compact offsets (+0300) to extended form before parsing.","Validate the offset component with a regex before calling ParseISO8601."],"tags":["time-parsing","iso8601","timezone-offset","go"],"backgroundTag":"invalid-timezone-offset-format","analyzedSha":"7bedaf55a0b64bbb2248a5845a2c60d81a30996a","analyzedAt":"2026-08-30T20:38:16.250Z","schemaVersion":2},"datasetVersion":"2026-08-30T23:17:21.991Z"}