{"id":"fe1a917941960cc0","repo":"go-sql-driver/mysql","slug":"invalid-timetruncate-value-v-error-w","errorCode":null,"errorMessage":"invalid timeTruncate value: %v, error: %w","messagePattern":"invalid timeTruncate value: (.+?), error: %w","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"dsn.go","lineNumber":610,"sourceCode":"\t\t\tvar isBool bool\n\t\t\tcfg.MultiStatements, isBool = readBool(value)\n\t\t\tif !isBool {\n\t\t\t\treturn errors.New(\"invalid bool value: \" + value)\n\t\t\t}\n\n\t\t// time.Time parsing\n\t\tcase \"parseTime\":\n\t\t\tvar isBool bool\n\t\t\tcfg.ParseTime, isBool = readBool(value)\n\t\t\tif !isBool {\n\t\t\t\treturn errors.New(\"invalid bool value: \" + value)\n\t\t\t}\n\n\t\t// time.Time truncation\n\t\tcase \"timeTruncate\":\n\t\t\tcfg.timeTruncate, err = time.ParseDuration(value)\n\t\t\tif err != nil {\n\t\t\t\treturn fmt.Errorf(\"invalid timeTruncate value: %v, error: %w\", value, err)\n\t\t\t}\n\n\t\t// I/O read Timeout\n\t\tcase \"readTimeout\":\n\t\t\tcfg.ReadTimeout, err = time.ParseDuration(value)\n\t\t\tif err != nil {\n\t\t\t\treturn\n\t\t\t}\n\n\t\t// Reject read-only connections\n\t\tcase \"rejectReadOnly\":\n\t\t\tvar isBool bool\n\t\t\tcfg.RejectReadOnly, isBool = readBool(value)\n\t\t\tif !isBool {\n\t\t\t\treturn errors.New(\"invalid bool value: \" + value)\n\t\t\t}\n\n\t\t// Server public key","sourceCodeStart":592,"sourceCodeEnd":628,"githubUrl":"https://github.com/go-sql-driver/mysql/blob/c426bd93799de0f0e094c8f0582872c529d0ed0a/dsn.go#L592-L628","documentation":"Returned by the DSN parser when the `timeTruncate` query parameter cannot be parsed by Go's time.ParseDuration. The `timeTruncate` feature truncates time.Time values to a fixed duration (e.g. to the second) before writing them to the wire via appendDateTime (connection.go:380, packets.go:1211). A malformed duration string aborts DSN parsing entirely.","triggerScenarios":"Calling mysql.ParseDSN or sql.Open with a DSN whose timeTruncate value is not a valid Go duration, e.g. `?timeTruncate=abc`, `?timeTruncate=1` (bare number with no unit), or `?timeTruncate=1hour` (Go wants `1h`). The error is produced at dsn.go:610 when time.ParseDuration returns non-nil.","commonSituations":"Translating a duration from another language/notation into the DSN; forgetting that Go durations require a unit suffix; typos like `timeTruncate=1h30m` is valid but `timeTruncate=1:30` is not; copying a DSN template that used a non-Go duration format.","solutions":["Use a valid Go duration string with a unit: `timeTruncate=1s`, `1m`, `500ms`, `1h`, or `1h30m`.","Remove the timeTruncate parameter entirely if you do not need truncation; it is optional.","Validate the duration in Go with time.ParseDuration before interpolating it into the DSN."],"exampleFix":"// before\nsql.Open(\"mysql\", \"u:p@tcp(127.0.0.1:3306)/db?parseTime=true&timeTruncate=1sec\")\n// after\nsql.Open(\"mysql\", \"u:p@tcp(127.0.0.1:3306)/db?parseTime=true&timeTruncate=1s\")","handlingStrategy":"validation","validationCode":"if _, err := time.ParseDuration(rawTimeTruncate); err != nil {\n    return fmt.Errorf(\"timeTruncate must be a Go duration (e.g. 1s, 500ms): %w\", err)\n}","typeGuard":"func validDuration(s string) bool { _, err := time.ParseDuration(s); return err == nil }","tryCatchPattern":null,"preventionTips":["Build DSNs from a Config struct and call FormatDSN so durations are serialized correctly.","Unit-test DSN generation against mysql.ParseDSN.","Never interpolate raw user input as a duration."],"tags":["config","dsn","time","validation"],"analyzedSha":"c426bd93799de0f0e094c8f0582872c529d0ed0a","analyzedAt":"2026-08-04T21:52:59.219Z","schemaVersion":2}