hibiken/asynq · error
unexpected return value from script
Error message
unexpected return value from script: %v
What it means
Returned by RDB archive-all operations when the archiveAllCmd Lua script yields a value that is not int64. The script is expected to return an integer count of archived tasks (or -1 for a missing queue); any other reply type fails this assertion. It signals an unexpected Redis reply rather than an application-level problem.
Solutions
- Confirm standard Redis is used and returns integer replies from EVAL
- Verify internal Lua scripts match the asynq release
- Inspect the logged value to identify the actual returned type
- Upgrade asynq and go-redis to compatible versions
Defensive patterns
Strategy: try-catch
Validate before calling
paused, err := inspector.ArchivedSize(q) _ = paused // verify Redis connectivity/reply types before bulk archive ops
Type guard
func isInt64(res interface{}) bool {
_, ok := res.(int64)
return ok
} Try / catch
n, err := inspector.ArchiveAllPendingTasks(q)
if err != nil {
if strings.Contains(err.Error(), "unexpected return value from script") {
// log the reply, escalate to standard-Redis check
}
return err
} Prevention
- Avoid Redis proxies that reshape Lua replies
- Keep internal Lua scripts unmodified
- Test archive ops against the real cluster
- Monitor for repeated occurrences indicating server drift
When it happens
Trigger: Calling ArchiveAllPendingTasks (or similar archive-all APIs) where the Lua script's Result() is a string, redis.Message, or nil instead of int64 — typically due to a non-standard Redis server or altered reply handling.
Common situations: Redis proxies/clusters that reshape EVAL replies; custom Redis forks; running an asynq build with mismatched internal scripts.
Related errors
- could not cast to int64
- unexpected return value from Lua 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/1ed02ee84996ad63.
Report an issue: GitHub.
Appendix: source
Thrown at internal/rdb/inspect.go:1422
keys := []string{
src,
dst,
}
now := r.clock.Now()
argv := []interface{}{
now.Unix(),
now.AddDate(0, 0, -archivedExpirationInDays).Unix(),
maxArchiveSize,
base.TaskKeyPrefix(qname),
qname,
}
res, err := archiveAllCmd.Run(context.Background(), r.client, keys, argv...).Result()
if err != nil {
return 0, err
}
n, ok := res.(int64)
if !ok {
return 0, fmt.Errorf("unexpected return value from script: %v", res)
}
if n == -1 {
return 0, &errors.QueueNotFoundError{Queue: qname}
}
return n, nil
}
// Input:
// KEYS[1] -> asynq:{<qname>}:t:<task_id>
// --
// ARGV[1] -> task message data
//
// Output:
// Numeric code indicating the status:
// Returns 1 if task is successfully updated.
// Returns 0 if task is not found.
// Returns -1 if task is not in scheduled state.
var updateTaskPayloadCmd = redis.NewScript(`View on GitHub (pinned to d135f1439b)