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

  1. Confirm standard Redis is used and returns integer replies from EVAL
  2. Verify internal Lua scripts match the asynq release
  3. Inspect the logged value to identify the actual returned type
  4. 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

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


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)