hibiken/asynq · error
unexpected return value from Lua script
Error message
unexpected return value from Lua script: %v
What it means
Returned by RDB delete-all operations (deleteAllCmd) when the Lua script returns something other than an int64. The script should return the number of deleted tasks as an integer; this guard rejects any other reply type. As with the sibling errors, it indicates a Redis reply-protocol deviation.
Solutions
- Test the script directly with redis-cli EVAL to inspect the reply type
- Ensure the Redis server is unmodified standard Redis
- Check the actual value in the error message for type clues
- Pin asynq and go-redis versions and retest
Defensive patterns
Strategy: try-catch
Validate before calling
_ = inspector.QueueSize(q) // smoke-test EVAL integer replies before delete-all
Type guard
func toInt64(res interface{}) (int64, bool) {
switch v := res.(type) {
case int64: return v, true
case string:
n, err := strconv.ParseInt(v, 10, 64)
return n, err == nil
}
return 0, false
} Try / catch
n, err := inspector.DeleteAllPendingTasks(q)
if err != nil {
if strings.Contains(err.Error(), "unexpected return value from Lua script") {
// verify server with redis-cli EVAL before retrying destructive op
}
return err
} Prevention
- Never patch internal Lua scripts without testing reply types
- Use standard Redis builds in production
- Validate EVAL replies with redis-cli when in doubt
- Gate destructive delete-all ops behind connectivity/compat checks
When it happens
Trigger: Calling DeleteAllPendingTasks (or sibling delete-all methods) where the script's Result() cannot be asserted to int64 — non-standard Redis server, proxy rewriting replies, or patched scripts.
Common situations: Redis-compatible services with differing Lua reply semantics; version drift between asynq's scripts and the server; debugging with a RESP proxy.
Related errors
- could not cast to int64
- unexpected return value from script
- rate.NewSemaphore: unsupported RedisConnOpt type %T
- task already exists
- task ID conflicts with another task
AI-assisted analysis of hibiken/asynq@d135f1439b (2026-09-07).
Data as JSON: /api/errors/632cf0bcc37c497d.
Report an issue: GitHub.
Appendix: source
Thrown at internal/rdb/inspect.go:1693
end
redis.call("DEL", KEYS[1])
return table.getn(ids)`)
func (r *RDB) deleteAll(key, qname string) (int64, error) {
if err := r.checkQueueExists(qname); err != nil {
return 0, err
}
argv := []interface{}{
base.TaskKeyPrefix(qname),
qname,
}
res, err := deleteAllCmd.Run(context.Background(), r.client, []string{key}, argv...).Result()
if err != nil {
return 0, err
}
n, ok := res.(int64)
if !ok {
return 0, fmt.Errorf("unexpected return value from Lua script: %v", res)
}
return n, nil
}
// deleteAllAggregatingCmd deletes all tasks from the given group.
//
// Input:
// KEYS[1] -> asynq:{<qname>}:g:<gname>
// KEYS[2] -> asynq:{<qname>}:groups
// -------
// ARGV[1] -> task key prefix
// ARGV[2] -> group name
var deleteAllAggregatingCmd = redis.NewScript(`
local ids = redis.call("ZRANGE", KEYS[1], 0, -1)
for _, id in ipairs(ids) do
redis.call("DEL", ARGV[1] .. id)
end
redis.call("SREM", KEYS[2], ARGV[2])View on GitHub (pinned to d135f1439b)