redis/redis-py · error · DataError
HIMPORT fields must be a collection of field names, not a si
Error message
HIMPORT fields must be a collection of field names, not a single string or binary value
What it means
Raised as redis.exceptions.DataError by HImportRegistry._materialize_fields (redis/himport.py:242). The HIMPORT fieldset must be a collection of field names; a bare str/bytes/bytearray/memoryview is itself iterable character-by-character and would silently register single-character 'fields' (e.g. memoryview(b'id') -> fields 105, 100). To prevent that footgun the registry rejects single scalar values up front.
Source
Thrown at redis/himport.py:242
@staticmethod
def _materialize_fields(fields: Iterable[FieldT]) -> tuple:
"""Validate and materialize the caller's field iterable into a tuple.
Done *before* the mutation lock is taken: consuming an arbitrary iterable
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(),
)View on GitHub (pinned to da03cdc7e8)
Solutions
- Always pass a list/tuple of field names, even for one field: ['email'] not 'email'.
- For bytes field names, wrap in a collection: [b'email'].
- Add a helper that normalizes a single name into a one-element list at your call boundary.
Example fix
// before
registry.prepare('account_data', 'email')
// after
registry.prepare('account_data', ['email']) Defensive patterns
Strategy: validation
Validate before calling
from collections.abc import Iterable
from typing import Union
def as_field_collection(fields):
if isinstance(fields, (str, bytes, bytearray, memoryview)):
return [fields] # wrap a lone name
return list(fields)
registry.prepare('account_data', as_field_collection(fields_arg)) Type guard
from collections.abc import Iterable
def is_field_collection(v) -> bool:
return isinstance(v, Iterable) and not isinstance(v, (str, bytes, bytearray, memoryview)) Prevention
- Always pass a list/tuple of field names, even for a single field.
- Normalize single-name inputs into a one-element list at your call boundary.
- Add a unit test that prepare() rejects a bare string, catching the regression.
When it happens
Trigger: Calling registry.prepare(name, 'email') or client-side HIMPORT PREPARE with a single string instead of a list/tuple of field names.
Common situations: Forgetting to wrap a lone field name in a list; passing a bytes field name; confusing the single-name API with the field-collection API.
Related errors
- HIMPORT fieldset must have at least one field
- CLIENT KILL type must be one of {client_types!r}
- CLIENT KILL skipme must be a bool
- CLIENT KILL <filter> <value> ... ... <filter> <value> must s
- CLIENT LIST _type must be one of {client_types!r}
AI-assisted analysis of redis/redis-py@da03cdc7e8 (2026-08-04).
Data as JSON: /data/errors/548c2418183d3879.json.
Report an issue: GitHub.