redis/redis-py · error · DataError

HIMPORT fieldset must have at least one field

Error message

HIMPORT fieldset must have at least one field

What it means

Raised as redis.exceptions.DataError by HImportRegistry._materialize_fields (redis/himport.py:248). After materializing the caller's iterable into a tuple, an empty result means the fieldset declares no fields, which is meaningless for HIMPORT PREPARE (the server needs at least one field). The registry rejects it before touching any connection or server state.

Source

Thrown at redis/himport.py:248

        can be slow, or -- for a generator that inspects this same registry -- can
        re-enter a locked read (e.g. ``yield`` then ``registry.names()``). Running
        it under the non-reentrant ``_lock`` would stall every registry user or
        deadlock permanently. Field order is preserved; nothing is reordered or
        deduplicated.
        """
        # A bare single field name (str/bytes/bytearray/memoryview) is itself
        # iterable element-by-element; that is almost certainly a caller mistake and
        # would silently register single-character/single-byte "fields" (e.g.
        # memoryview(b"id") -> field names 105, 100), so reject it as invalid local
        # API usage. int/float are not iterable, so tuple() below rejects them.
        if isinstance(fields, (str, bytes, bytearray, memoryview)):
            raise DataError(
                "HIMPORT fields must be a collection of field names, "
                "not a single string or binary value"
            )
        field_tuple = tuple(fields)
        if not field_tuple:
            raise DataError("HIMPORT fieldset must have at least one field")
        return field_tuple

    def _set(self, name: str, field_tuple: tuple) -> HImportFieldset:
        # ``field_tuple`` is already validated/materialized by
        # :meth:`_materialize_fields`; only the (cheap, non-blocking) revision bump
        # and dict mutation run here, so ``_lock`` is never held across arbitrary
        # caller code.
        fieldset = HImportFieldset(
            name=name,
            fields=field_tuple,
            version=self._advance(),
        )
        self._fieldsets[name] = fieldset
        return fieldset

    # -- mutation ---------------------------------------------------------

    def prepare(self, name: str, fields: Iterable[FieldT]) -> HImportFieldset:

View on GitHub (pinned to da03cdc7e8)

Solutions

  1. Ensure the field collection is non-empty before calling prepare().
  2. Validate at the source: if the field list is empty, skip the prepare or raise a clearer domain error.
  3. Guard dynamic field generation so it always yields at least one field.

Example fix

// before
fields = [f for f in config_fields if f.active]  # could be empty
registry.prepare('account_data', fields)

// after
fields = [f for f in config_fields if f.active]
if not fields:
    raise ValueError('no active fields configured')
registry.prepare('account_data', fields)
Defensive patterns

Strategy: validation

Validate before calling

fields = list(candidate_fields)
if not fields:
    raise ValueError('field collection is empty')
registry.prepare('account_data', fields)

Type guard

def is_nonempty_collection(v) -> bool:
    try:
        return len(list(v)) > 0
    except TypeError:
        return False

Prevention

When it happens

Trigger: Calling registry.prepare(name, []) or with an iterable that yields zero elements (an empty generator, a filtered list with no matches).

Common situations: Passing an empty list by mistake; a list comprehension that produced nothing; a config-driven field list that was not populated.

Related errors


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