{"id":"ba68ebc5cfe72c31","repo":"go-redis/redis","slug":"redis-invalid-database-number-w","errorCode":null,"errorMessage":"redis: invalid database number: %w","messagePattern":"redis: invalid database number: %w","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"options.go","lineNumber":845,"sourceCode":"\nfunc (o *queryOptions) remaining() []string {\n\tif len(o.q) == 0 {\n\t\treturn nil\n\t}\n\tkeys := slices.Collect(maps.Keys(o.q))\n\tslices.Sort(keys)\n\treturn keys\n}\n\n// setupConnParams converts query parameters in u to option value in o.\nfunc setupConnParams(u *url.URL, o *Options) (*Options, error) {\n\tq := queryOptions{q: u.Query()}\n\n\t// compat: a future major release may use q.int(\"db\")\n\tif tmp := q.string(\"db\"); tmp != \"\" {\n\t\tdb, err := strconv.Atoi(tmp)\n\t\tif err != nil {\n\t\t\treturn nil, fmt.Errorf(\"redis: invalid database number: %w\", err)\n\t\t}\n\t\to.DB = db\n\t}\n\n\to.Protocol = q.int(\"protocol\")\n\to.ClientName = q.string(\"client_name\")\n\to.MaxRetries = q.int(\"max_retries\")\n\to.MinRetryBackoff = q.duration(\"min_retry_backoff\")\n\to.MaxRetryBackoff = q.duration(\"max_retry_backoff\")\n\to.DialTimeout = q.duration(\"dial_timeout\")\n\to.ReadTimeout = q.duration(\"read_timeout\")\n\to.WriteTimeout = q.duration(\"write_timeout\")\n\to.PoolFIFO = q.bool(\"pool_fifo\")\n\to.PoolSize = q.int(\"pool_size\")\n\to.PoolTimeout = q.duration(\"pool_timeout\")\n\to.MinIdleConns = q.int(\"min_idle_conns\")\n\to.MaxIdleConns = q.int(\"max_idle_conns\")\n\to.MaxActiveConns = q.int(\"max_active_conns\")","sourceCodeStart":827,"sourceCodeEnd":863,"githubUrl":"https://github.com/go-redis/redis/blob/36d97525cd8076aed67cddf54778e9ea84550929/options.go#L827-L863","documentation":"Returned by setupConnParams when the legacy ?db=N query parameter is present but cannot be parsed as an integer with strconv.Atoi. Unlike the path DB selector, this wraps the underlying strconv error with %w so the original parse failure is preserved.","triggerScenarios":"A URL like redis://host:6379/?db=zero or redis://host:6379/?db=1.0. The db query parameter is the preferred way to set the DB while keeping the path empty.","commonSituations":"Mistyping the DB index, passing a float, or a templating bug that injects a non-numeric placeholder.","solutions":["Use an integer for ?db=N (e.g. ?db=2).","Drop the parameter and rely on the path /N or Options.DB.","Validate the value is numeric before assembling the URL."],"exampleFix":"// before\nopt, err := redis.ParseURL(\"redis://localhost:6379/?db=two\")\n// after\nopt, err := redis.ParseURL(\"redis://localhost:6379/?db=2\")","handlingStrategy":"validation","validationCode":"func validDBParam(s string) bool { _, err := strconv.Atoi(s); return err == nil }","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Use an integer for ?db=N.","Prefer the path form or Options.DB if the value is dynamic.","Validate numeric DB values at config load."],"tags":["config","url","validation"],"analyzedSha":"36d97525cd8076aed67cddf54778e9ea84550929","analyzedAt":"2026-08-06T01:08:27.376Z","schemaVersion":2}