redis/go-redis · error
both LibName and LibVer cannot be set at the same time
Error message
both LibName and LibVer cannot be set at the same time
What it means
LibraryInfo.Validate enforces that a CLIENT SETINFO command sets exactly one of LibName or LibVer. The go-redis API exposes these as *string pointers so nil vs empty can be distinguished, and passing both is rejected because the Redis CLIENT SETINFO protocol accepts only one attribute per call.
Source
Thrown at commands.go:351
panic(err.Error())
}
var cmd *StatusCmd
if info.LibName != nil {
libName := fmt.Sprintf("go-redis(%s,%s)", *info.LibName, internal.ReplaceSpaces(runtime.Version()))
cmd = NewStatusCmd(ctx, "client", "setinfo", "LIB-NAME", libName)
} else {
cmd = NewStatusCmd(ctx, "client", "setinfo", "LIB-VER", *info.LibVer)
}
_ = c(ctx, cmd)
return cmd
}
// Validate checks if only one field in the struct is non-nil.
func (info LibraryInfo) Validate() error {
if info.LibName != nil && info.LibVer != nil {
return errors.New("both LibName and LibVer cannot be set at the same time")
}
if info.LibName == nil && info.LibVer == nil {
return errors.New("at least one of LibName and LibVer should be set")
}
return nil
}
// Hello sets the resp protocol used.
func (c statefulCmdable) Hello(ctx context.Context,
ver int, username, password, clientName string,
) *MapStringInterfaceCmd {
args := make([]interface{}, 0, 7)
args = append(args, "hello", ver)
if password != "" {
if username != "" {
args = append(args, "auth", username, password)
} else {
args = append(args, "auth", "default", password)View on GitHub (pinned to c5cad058c7)
Solutions
- Set only one field per LibraryInfo value and issue two ClientSetInfo calls: one for LibName, one for LibVer.
- If you only need the library name, drop LibVer from the struct.
- If you only need the version, drop LibName.
Example fix
// before
rdb.ClientSetInfo(ctx, redis.LibraryInfo{LibName: redis.StringPtr("myapp"), LibVer: redis.StringPtr("1.0")})
// after
rdb.ClientSetInfo(ctx, redis.LibraryInfo{LibName: redis.StringPtr("myapp")})
rdb.ClientSetInfo(ctx, redis.LibraryInfo{LibVer: redis.StringPtr("1.0")}) Defensive patterns
Strategy: validation
Validate before calling
func validLibInfo(info redis.LibraryInfo) bool {
return (info.LibName == nil) != (info.LibVer == nil)
}
if !validLibInfo(info) { /* fix before calling */ } Type guard
func hasExactlyOne(info redis.LibraryInfo) bool {
n := 0
if info.LibName != nil { n++ }
if info.LibVer != nil { n++ }
return n == 1
} Prevention
- Send LibName and LibVer as two separate ClientSetInfo calls.
- Use redis.StringPtr explicitly so nil-vs-empty is intentional.
- Add a unit test asserting exactly one field is set.
When it happens
Trigger: Calling ClientSetInfo with a LibraryInfo where both LibName and LibVer are non-nil, e.g. redis.LibraryInfo{LibName: redis.StringPtr("myapp"), LibVer: redis.StringPtr("1.2.0")}.
Common situations: Developers assuming the method sends both attributes at once, or trying to mirror the redis-cli syntax; wrapping what should be two calls into one struct.
Related errors
- at least one of LibName and LibVer should be set
- redis: CLIENT TRACKING OPTIN and OPTOUT are mutually exclusi
- redis: CLIENT TRACKING BCAST cannot be combined with OPTIN o
- redis: CLIENT TRACKING PREFIX requires BCAST
- MemoryUsage expects single sample count
AI-assisted analysis of redis/go-redis@c5cad058c7 (2026-09-01).
Data as JSON: /api/errors/49e0030ae7a310a5.
Report an issue: GitHub.