redis/redis-py · error · RuntimeError

index_type must be one of

Error message

index_type must be one of {list(IndexType)}

What it means

Raised by IndexDefinition._append_index_type() (redis/commands/search/index_definition.py:43) as a RuntimeError when index_type is not None, IndexType.HASH, or IndexType.JSON. Crucially the checks use identity (is), so passing the strings 'HASH' or 'JSON' does NOT match - you must pass the enum member. The message prints list(IndexType) which renders as [<IndexType.HASH: 1>, <IndexType.JSON: 2>] rather than friendly strings.

Solutions

  1. Import and pass the enum: from redis.commands.search.index_definition import IndexType; IndexDefinition(index_type=IndexType.HASH).
  2. If your config is a string, map it: IndexType[config_str.upper()].
  3. Omit index_type (None) if you want the server default.

Example fix

# before
IndexDefinition(prefix=['doc:'], index_type='JSON')
# after
from redis.commands.search.index_definition import IndexType
IndexDefinition(prefix=['doc:'], index_type=IndexType.JSON)
Defensive patterns

Strategy: type-guard

Validate before calling

from redis.commands.search.index_definition import IndexType, IndexDefinition

def safe_index_type(value):
    if value is None or isinstance(value, IndexType):
        return value
    if isinstance(value, str):
        return IndexType[value.upper()]
    raise ValueError('index_type must be IndexType.HASH, IndexType.JSON, or None')

Type guard

from redis.commands.search.index_definition import IndexType

def is_valid_index_type(v) -> bool:
    return v is None or isinstance(v, IndexType)

Try / catch

try:
    IndexDefinition(prefix=['doc:'], index_type=it)
except RuntimeError as e:
    if 'index_type' in str(e):
        IndexDefinition(prefix=['doc:'], index_type=IndexType[it.upper()])
    else:
        raise

Prevention

When it happens

Trigger: Calling IndexDefinition(index_type='HASH'), IndexDefinition(index_type='json'), or any non-enum value. Passing IndexType.HASH or IndexType.JSON works; passing the raw string does not.

Common situations: Reading index type from config as a string and passing it directly, or assuming the constructor accepts strings like other parts of the API. The unhelpful message rendering makes the fix non-obvious.

Related errors


AI-assisted analysis of redis/redis-py@6a6b581b48 (2026-08-10). Data as JSON: /api/errors/befc22cc7e97b9f4. Report an issue: GitHub.

Appendix: source

Thrown at redis/commands/search/index_definition.py:43

        payload_field=None,
        index_type=None,
    ):
        self.args = []
        self._append_index_type(index_type)
        self._append_prefix(prefix)
        self._append_filter(filter)
        self._append_language(language_field, language)
        self._append_score(score_field, score)
        self._append_payload(payload_field)

    def _append_index_type(self, index_type):
        """Append `ON HASH` or `ON JSON` according to the enum."""
        if index_type is IndexType.HASH:
            self.args.extend(["ON", "HASH"])
        elif index_type is IndexType.JSON:
            self.args.extend(["ON", "JSON"])
        elif index_type is not None:
            raise RuntimeError(f"index_type must be one of {list(IndexType)}")

    def _append_prefix(self, prefix):
        """Append PREFIX."""
        if prefix is None:
            raise TypeError("prefix must be provided")
        if len(prefix) > 0:
            prefix = list_or_args(prefix, [])
            self.args.append("PREFIX")
            self.args.append(len(prefix))
            for p in prefix:
                self.args.append(p)

    def _append_filter(self, filter):
        """Append FILTER."""
        if filter is not None:
            self.args.append("FILTER")
            self.args.append(filter)

View on GitHub (pinned to 6a6b581b48)