hibiken/asynq · critical
asynq: unsupported RedisConnOpt type %T
Error message
asynq: unsupported RedisConnOpt type %T
What it means
asynq.NewScheduler panics when the provided RedisConnOpt's MakeRedisClient() does not return a redis.UniversalClient. Like NewClient and NewServer, the scheduler only supports connection options backed by a go-redis UniversalClient, and an incompatible implementation causes an immediate panic at construction time.
Solutions
- Use built-in options: asynq.RedisClientOpt, RedisClusterClientOpt, or RedisFailoverClientOpt
- If you already hold a go-redis client, build the Scheduler via NewScheduler with a valid option or adapt using an asynq-supported client constructor
- Make the custom RedisConnOpt's MakeRedisClient return a redis.UniversalClient-implementing value
- Assert compatibility in a small startup check: if _, ok := r.MakeRedisClient().(redis.UniversalClient); !ok { fail fast with a clear message }
Example fix
// before
sched := asynq.NewScheduler(brokenOpt{}, nil) // panics
// after
sched, err := asynq.NewScheduler(asynq.RedisClientOpt{Addr: ":6379"}, nil)
if err != nil { log.Fatal(err) } Defensive patterns
Strategy: validation
Validate before calling
opt := asynq.RedisClientOpt{Addr: ":6379"}
if _, ok := opt.MakeRedisClient().(redis.UniversalClient); !ok {
log.Fatal("scheduler RedisConnOpt incompatible")
}
sched := asynq.NewScheduler(opt, nil) Type guard
func schedConnOptValid(r asynq.RedisConnOpt) bool {
_, ok := r.MakeRedisClient().(redis.UniversalClient)
return ok
} Prevention
- Use built-in conn-opt types for NewScheduler
- Share one validated RedisConnOpt factory across Client/Server/Scheduler/Inspector
- Pin a go-redis version compatible with your asynq version
- Add a unit test constructing the scheduler with the production option
When it happens
Trigger: Passing a custom RedisConnOpt whose MakeRedisClient returns nil or a non-go-redis client type; using a wrapper/adapter struct; passing an option type from an incompatible go-redis major version.
Common situations: Building the scheduler with the same (broken) custom conn opt already used elsewhere; config-driven construction where an unvalidated config value produces a foreign conn-opt type; mixing asynq versions with different go-redis dependencies.
Understand the failure class
Background: Type mismatch errors: IllegalArgumentException, TypeError and type guards across 150 open-source libraries — this error's family across 150 libraries.
Related errors
- asynq: unsupported RedisConnOpt type %T
- inspeq: unsupported RedisConnOpt type %T
- asynq: unsupported RedisConnOpt type %T
- asynq: could not parse redis uri
- asynq: unsupported uri scheme
AI-assisted analysis of hibiken/asynq@d135f1439b (2026-09-07).
Data as JSON: /api/errors/1f3b25abec3c5e39.
Report an issue: GitHub.
Appendix: source
Thrown at scheduler.go:58
// guards idmap
mu sync.Mutex
// idmap maps Scheduler's entry ID to cron.EntryID
// to avoid using cron.EntryID as the public API of
// the Scheduler.
idmap map[string]cron.EntryID
}
const defaultHeartbeatInterval = 10 * time.Second
// NewScheduler returns a new Scheduler instance given the redis connection option.
// The parameter opts is optional, defaults will be used if opts is set to nil
func NewScheduler(r RedisConnOpt, opts *SchedulerOpts) *Scheduler {
scheduler := newScheduler(opts)
redisClient, ok := r.MakeRedisClient().(redis.UniversalClient)
if !ok {
panic(fmt.Sprintf("asynq: unsupported RedisConnOpt type %T", r))
}
rdb := rdb.NewRDB(redisClient)
scheduler.rdb = rdb
scheduler.client = &Client{broker: rdb, sharedConnection: false}
return scheduler
}
// NewSchedulerFromRedisClient returns a new instance of Scheduler given a redis.UniversalClient
// The parameter opts is optional, defaults will be used if opts is set to nil.
// Warning: The underlying redis connection pool will not be closed by Asynq, you are responsible for closing it.
func NewSchedulerFromRedisClient(c redis.UniversalClient, opts *SchedulerOpts) *Scheduler {
scheduler := newScheduler(opts)
scheduler.rdb = rdb.NewRDB(c)
scheduler.client = NewClientFromRedisClient(c)View on GitHub (pinned to d135f1439b)