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

  1. Set only one field per LibraryInfo value and issue two ClientSetInfo calls: one for LibName, one for LibVer.
  2. If you only need the library name, drop LibVer from the struct.
  3. 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

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


AI-assisted analysis of redis/go-redis@c5cad058c7 (2026-09-01). Data as JSON: /api/errors/49e0030ae7a310a5. Report an issue: GitHub.