bytebase/bytebase · error
expect *redis.ClusterClient, but get %T
Error message
expect *redis.ClusterClient, but get %T
What it means
With QueryOption_ALL_NODES, QueryConn must fan a command out to every node of a Redis cluster, so it asserts d.rdb is a *redis.ClusterClient. If the underlying client is a plain Client (standalone/sentinel) instead, the type assertion fails and the error names the actual concrete type received.
Source
Thrown at backend/plugin/db/redis/redis.go:274
for _, input := range inputs {
cmd := p.Do(ctx, input...)
cmds = append(cmds, cmd)
}
return nil
}); err != nil && err != redis.Nil {
return nil, err
}
for i, cmd := range cmds {
setQueryResultRows(results[i], cmd, queryContext.MaximumSQLResultSize)
results[i].Latency = durationpb.New(time.Since(startTime))
results[i].RowsCount = int64(len(results[i].Rows))
}
case v1pb.QueryOption_ALL_NODES:
cluster, ok := d.rdb.(*redis.ClusterClient)
if !ok {
return nil, errors.Errorf("expect *redis.ClusterClient, but get %T", d.rdb)
}
var cmdss [][]*redis.Cmd
cmdsChan := make(chan []*redis.Cmd)
stopChan := make(chan struct{})
go func() {
for {
select {
case cmds := <-cmdsChan:
cmdss = append(cmdss, cmds)
case <-stopChan:
return
}
}
}()
err := cluster.ForEachShard(ctx, func(ctx context.Context, client *redis.Client) error {
var cmds []*redis.CmdView on GitHub (pinned to 1870550677)
Solutions
- Don't use the ALL_NODES query option unless the instance is a Redis cluster.
- Change the instance's redisType to CLUSTER if it truly is a cluster so d.rdb is a ClusterClient.
- Re-run the query with the default (single-node) query option instead.
Example fix
// before: ALL_NODES on a standalone instance queryContext.Option.QueryType = v1pb.QueryOption_ALL_NODES // after: use default/single-node execution queryContext.Option.QueryType = v1pb.QueryOption_BASIC
Defensive patterns
Strategy: type-guard
Validate before calling
if qCtx.Option.QueryType == v1pb.QueryOption_ALL_NODES && cfg.DataSource.GetRedisType() != storepb.DataSource_REDIS_TYPE_CLUSTER {
log.Fatal("ALL_NODES requires a Redis cluster instance")
} Type guard
cluster, ok := d.rdb.(*redis.ClusterClient)
if !ok {
return nil, fmt.Errorf("ALL_NODES unsupported: client is %T", d.rdb)
} Try / catch
results, err := d.QueryConn(ctx, conn, stmt, qCtx)
if err != nil && strings.Contains(err.Error(), "expect *redis.ClusterClient") {
// fall back to single-node query
} Prevention
- Only enable ALL_NODES for instances whose redisType is CLUSTER.
- Verify instance type in settings before cluster-only operations.
- Wrap with a type assertion when writing plugin-level code.
When it happens
Trigger: Executing a query with QueryOption_ALL_NODES against an instance configured as STANDALONE or SENTINEL — the rdb field holds redis.Client/SentinelClient, not redis.ClusterClient.
Common situations: Users selecting the "run on all nodes" option for a non-cluster Redis; instance type misconfigured (configured as standalone but actually cluster, or vice versa).
Understand the failure class
Background: "is not a compatible type" / "cannot merge" errors: when a value's type doesn't match what the library requires — this error's family across 65 libraries.
Related errors
- failed to query for each shard
- unknown RedisRunCommandOn enum %v
- redis: cannot create database
- Redis does not support EXPLAIN
- failed to get redis_version
AI-assisted analysis of bytebase/bytebase@1870550677 (2026-09-06).
Data as JSON: /api/errors/fe804a0d296a1571.
Report an issue: GitHub.