{"record":{"id":"32abfe11f26b3da8","repo":"cayleygraph/cayley","slug":"couldn-t-parse-connmaxlifetime-string-v","errorCode":null,"errorMessage":"couldn't parse connmaxlifetime string: %v","messagePattern":"couldn't parse connmaxlifetime string: (.+?)","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"graph/sql/quadstore.go","lineNumber":142,"sourceCode":"\n\tmaxIdleConnections, err := opts.IntKey(\"maxidleconnections\", -1)\n\n\tif err != nil {\n\t\treturn nil, fmt.Errorf(\"could not retrieve maxIdleConnections from options: %v\", err)\n\t}\n\n\tconnMaxLifetime, err := opts.StringKey(\"connmaxlifetime\", \"\")\n\n\tif err != nil {\n\t\treturn nil, fmt.Errorf(\"could not retrieve connmaxlifetime from options: %v\", err)\n\t}\n\n\tvar connDuration time.Duration\n\tif connMaxLifetime != \"\" {\n\t\tconnDuration, err = time.ParseDuration(connMaxLifetime)\n\n\t\tif err != nil {\n\t\t\treturn nil, fmt.Errorf(\"couldn't parse connmaxlifetime string: %v\", err)\n\t\t}\n\t}\n\n\t// TODO(barakmich): Parse options for more friendly addr\n\tconn, err := sql.Open(flavor, addr)\n\tif err != nil {\n\t\tclog.Errorf(\"Couldn't open database at %s: %#v\", addr, err)\n\t\treturn nil, err\n\t}\n\n\t// \"Open may just validate its arguments without creating a connection to the database.\"\n\t// \"To verify that the data source name is valid, call Ping.\"\n\t// Source: http://golang.org/pkg/database/sql/#Open\n\tif err := conn.Ping(); err != nil {\n\t\tclog.Errorf(\"Couldn't open database at %s: %#v\", addr, err)\n\t\treturn nil, err\n\t}\n","sourceCodeStart":124,"sourceCodeEnd":160,"githubUrl":"https://github.com/cayleygraph/cayley/blob/81dcd7d73e45136bc0d01802a8ba4685d8a533eb/graph/sql/quadstore.go#L124-L160","documentation":"After reading \"connmaxlifetime\", connect parses it with time.ParseDuration. If the string isn't a valid Go duration (e.g. \"3600\", \"1 hr\"), the parse error is wrapped as \"couldn't parse connmaxlifetime string\". Reached via Init or New.","triggerScenarios":"New/Init where \"connmaxlifetime\" is a non-empty string that time.ParseDuration cannot parse — missing unit (\"3600\"), bad unit (\"1 hour\"), or malformed (\"1h30m20\").","commonSituations":"Admins writing seconds-as-number strings; config translated from other tools' formats (\"1 hour\", \"3600s\" is fine but \"1h \" with trailing space is not).","solutions":["Use a valid Go duration string with units, e.g. \"30m\", \"1h\", \"24h30m\".","Remember a bare number is invalid — it needs a unit suffix (\"3600s\" not \"3600\").","Trim whitespace from the config value before passing it."],"exampleFix":"// before\n{\"connmaxlifetime\": \"3600\"}\n// after\n{\"connmaxlifetime\": \"3600s\"}","handlingStrategy":"validation","validationCode":"if s, ok := opts[\"connmaxlifetime\"].(string); ok && s != \"\" {\n    if _, err := time.ParseDuration(s); err != nil {\n        return fmt.Errorf(\"connmaxlifetime is not a valid Go duration: %v\", err)\n    }\n}","typeGuard":null,"tryCatchPattern":"qs, err := quadstore.New(addr, opts)\nif err != nil {\n    if strings.Contains(err.Error(), \"couldn't parse connmaxlifetime\") {\n        // rewrite the value with an explicit unit, e.g. \"1h\"\n    }\n}","preventionTips":["Always include a unit suffix: \"1h\", \"30m\", \"3600s\" — never bare numbers.","Test the duration string with time.ParseDuration before deployment.","Trim whitespace from config values."],"tags":["sql","options","duration","config"],"backgroundTag":"invalid-duration-format","analyzedSha":"81dcd7d73e45136bc0d01802a8ba4685d8a533eb","analyzedAt":"2026-09-06T06:14:12.358Z","contentChangedAt":"2026-09-06T06:14:12.358Z","schemaVersion":2},"datasetVersion":"2026-09-14T00:17:10.932Z"}