redis/redis-py · error · ValueError

{field_name} must not contain spaces, newlines, non-printabl

Error message

{field_name} must not contain spaces, newlines, non-printable characters, or braces

What it means

Raised as ValueError by _validate_no_invalid_chars (redis/driver_info.py:21). Values that become the CLIENT SETINFO LIB-NAME/LIB-VER strings (driver name, version) are restricted to printable ASCII excluding spaces and braces, mirroring constraints other Redis clients enforce so the values are safe inside CLIENT LIST / CLIENT INFO output. Spaces, tabs, newlines, control chars, and any of ()[]{} are rejected.

Source

Thrown at redis/driver_info.py:21

from dataclasses import dataclass, field
from typing import List, Optional

from redis.utils import SENTINEL

_BRACES = {"(", ")", "[", "]", "{", "}"}


def _validate_no_invalid_chars(value: str, field_name: str) -> None:
    """Ensure value contains only printable ASCII without spaces or braces.

    This mirrors the constraints enforced by other Redis clients for values that
    will appear in CLIENT LIST / CLIENT INFO output.
    """

    for ch in value:
        # printable ASCII without space: '!' (0x21) to '~' (0x7E)
        if ord(ch) < 0x21 or ord(ch) > 0x7E or ch in _BRACES:
            raise ValueError(
                f"{field_name} must not contain spaces, newlines, non-printable characters, or braces"
            )


def _validate_driver_name(name: str) -> None:
    """Validate an upstream driver name.

    The name should look like a typical Python distribution or package name,
    following a simplified form of PEP 503 normalisation rules:

    * start with a lowercase ASCII letter
    * contain only lowercase letters, digits, hyphens and underscores

    Examples of valid names: ``"django-redis"``, ``"celery"``, ``"rq"``.
    """

    import re

View on GitHub (pinned to da03cdc7e8)

Solutions

  1. Strip/normalize the value to printable ASCII with no spaces or braces before passing it in.
  2. Use a machine-style identifier (lowercase, hyphens) for the name and a clean semver for the version.
  3. If you need a human label, keep it out of DriverInfo — it is only for CLIENT SETINFO, not display.

Example fix

// before
info.add_upstream_driver('My Redis Driver', '1.0.0\n')

// after
info.add_upstream_driver('my-redis-driver', '1.0.0')
Defensive patterns

Strategy: validation

Validate before calling

import re
_VALID = re.compile(r'^[!-~]+$')
_BRACES = set('()[]{}')
def clean_driver_value(v: str, field: str) -> str:
    if not _VALID.match(v) or any(c in _BRACES for c in v):
        raise ValueError(f'{field} has invalid chars: {v!r}')
    return v
info.add_upstream_driver(clean_driver_value(name,'name'), clean_driver_value(version,'version'))

Type guard

import re
_BRACES = set('()[]{}')
def is_valid_driver_value(v) -> bool:
    return (
        isinstance(v, str)
        and v != ''
        and all(0x21 <= ord(c) <= 0x7E and c not in _BRACES for c in v)
    )

Prevention

When it happens

Trigger: Calling DriverInfo().add_upstream_driver(name, version) or constructing a Redis client with lib_name/lib_version containing a space, newline, tab, control character, or brace; the validation runs before the value is formatted into the SETINFO payload.

Common situations: Passing a 'friendly' display name with spaces (e.g. 'My Redis Driver'); a version string scraped from git that contains a newline; a value with parentheses copied from a package metadata field.

Related errors


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