redis/redis-py · error · DataError

frequency must be an integer

Error message

frequency must be an integer

What it means

restore() accepts an optional frequency eviction hint (LFU frequency counter) that must be an integer. The code calls int(frequency) in a try/except ValueError at core.py:2784-2787 and re-raises as DataError. Unlike the idletime message, this message is correctly spaced.

Source

Thrown at redis/commands/core.py:4287

        """
        params = [name, ttl, value]
        if replace:
            params.append("REPLACE")
        if absttl:
            params.append("ABSTTL")
        if idletime is not None:
            params.append("IDLETIME")
            try:
                params.append(int(idletime))
            except ValueError:
                raise DataError("idletimemust be an integer")

        if frequency is not None:
            params.append("FREQ")
            try:
                params.append(int(frequency))
            except ValueError:
                raise DataError("frequency must be an integer")

        return self.execute_command("RESTORE", *params)

    @overload
    def set(
        self: SyncClientProtocol,
        name: KeyT,
        value: EncodableT,
        ex: ExpiryT | None = ...,
        px: ExpiryT | None = ...,
        nx: bool = ...,
        xx: bool = ...,
        keepttl: bool = ...,
        get: bool = ...,
        exat: AbsExpiryT | None = ...,
        pxat: AbsExpiryT | None = ...,
        ifeq: bytes | str | None = ...,
        ifne: bytes | str | None = ...,

View on GitHub (pinned to da03cdc7e8)

Solutions

  1. Pass an int for frequency, e.g. r.restore('k', 0, blob, frequency=5).
  2. Coerce upstream: frequency = int(frequency) before the call.
  3. Omit frequency if you are not restoring LFU metadata.

Example fix

# before
r.restore('k', 0, blob, frequency=freq_str)

# after
r.restore('k', 0, blob, frequency=int(freq_str))
Defensive patterns

Strategy: validation

Validate before calling

if frequency is not None:
    frequency = int(frequency)  # raises early if non-numeric
r.restore('k', 0, blob, frequency=frequency)

Type guard

def is_int_like(v) -> bool:
    try:
        int(v)
        return True
    except (TypeError, ValueError):
        return False

Try / catch

from redis.exceptions import DataError
try:
    r.restore('k', 0, blob, frequency=frequency)
except DataError as e:
    if 'frequency' in str(e):
        r.restore('k', 0, blob, frequency=int(frequency))
    else:
        raise

Prevention

When it happens

Trigger: r.restore('k', 0, blob, frequency='abc') or any non-numeric string for frequency. Numeric strings like '5' coerce fine.

Common situations: Passing a deserialized/CLI frequency value as a string; LFU migration tooling that reads frequency from an exported format.

Related errors


AI-assisted analysis of redis/redis-py@da03cdc7e8 (2026-08-04). Data as JSON: /data/errors/551761017d40cefa.json. Report an issue: GitHub.