{"record":{"id":"632cf0bcc37c497d","repo":"hibiken/asynq","slug":"unexpected-return-value-from-lua-script-v","errorCode":null,"errorMessage":"unexpected return value from Lua script: %v","messagePattern":"unexpected return value from Lua script: (.+?)","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"internal/rdb/inspect.go","lineNumber":1693,"sourceCode":"end\nredis.call(\"DEL\", KEYS[1])\nreturn table.getn(ids)`)\n\nfunc (r *RDB) deleteAll(key, qname string) (int64, error) {\n\tif err := r.checkQueueExists(qname); err != nil {\n\t\treturn 0, err\n\t}\n\targv := []interface{}{\n\t\tbase.TaskKeyPrefix(qname),\n\t\tqname,\n\t}\n\tres, err := deleteAllCmd.Run(context.Background(), r.client, []string{key}, argv...).Result()\n\tif err != nil {\n\t\treturn 0, err\n\t}\n\tn, ok := res.(int64)\n\tif !ok {\n\t\treturn 0, fmt.Errorf(\"unexpected return value from Lua script: %v\", res)\n\t}\n\treturn n, nil\n}\n\n// deleteAllAggregatingCmd deletes all tasks from the given group.\n//\n// Input:\n// KEYS[1] -> asynq:{<qname>}:g:<gname>\n// KEYS[2] -> asynq:{<qname>}:groups\n// -------\n// ARGV[1] -> task key prefix\n// ARGV[2] -> group name\nvar deleteAllAggregatingCmd = redis.NewScript(`\nlocal ids = redis.call(\"ZRANGE\", KEYS[1], 0, -1)\nfor _, id in ipairs(ids) do\n\tredis.call(\"DEL\", ARGV[1] .. id)\nend\nredis.call(\"SREM\", KEYS[2], ARGV[2])","sourceCodeStart":1675,"sourceCodeEnd":1711,"githubUrl":"https://github.com/hibiken/asynq/blob/d135f1439bee74e989b7f9b41ecd542cc87f024a/internal/rdb/inspect.go#L1675-L1711","documentation":"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.","triggerScenarios":"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.","commonSituations":"Redis-compatible services with differing Lua reply semantics; version drift between asynq's scripts and the server; debugging with a RESP proxy.","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"],"exampleFix":null,"handlingStrategy":"try-catch","validationCode":"_ = inspector.QueueSize(q) // smoke-test EVAL integer replies before delete-all","typeGuard":"func toInt64(res interface{}) (int64, bool) {\n    switch v := res.(type) {\n    case int64: return v, true\n    case string:\n        n, err := strconv.ParseInt(v, 10, 64)\n        return n, err == nil\n    }\n    return 0, false\n}","tryCatchPattern":"n, err := inspector.DeleteAllPendingTasks(q)\nif err != nil {\n    if strings.Contains(err.Error(), \"unexpected return value from Lua script\") {\n        // verify server with redis-cli EVAL before retrying destructive op\n    }\n    return err\n}","preventionTips":["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"],"tags":["redis","lua","type-mismatch"],"backgroundTag":"unexpected-response-shape","analyzedSha":"d135f1439bee74e989b7f9b41ecd542cc87f024a","analyzedAt":"2026-09-07T19:02:34.660Z","contentChangedAt":"2026-09-07T19:02:34.660Z","schemaVersion":2},"datasetVersion":"2026-09-16T09:17:16.951Z"}