{"id":"5b69f275f555f9f4","repo":"redis/redis-py","slug":"field-name-must-not-contain-spaces-newlines-no","errorCode":null,"errorMessage":"{field_name} must not contain spaces, newlines, non-printable characters, or braces","messagePattern":"(.+?) must not contain spaces, newlines, non-printable characters, or braces","errorType":"validation","errorClass":"ValueError","httpStatus":null,"severity":"error","filePath":"redis/driver_info.py","lineNumber":21,"sourceCode":"from dataclasses import dataclass, field\nfrom typing import List, Optional\n\nfrom redis.utils import SENTINEL\n\n_BRACES = {\"(\", \")\", \"[\", \"]\", \"{\", \"}\"}\n\n\ndef _validate_no_invalid_chars(value: str, field_name: str) -> None:\n    \"\"\"Ensure value contains only printable ASCII without spaces or braces.\n\n    This mirrors the constraints enforced by other Redis clients for values that\n    will appear in CLIENT LIST / CLIENT INFO output.\n    \"\"\"\n\n    for ch in value:\n        # printable ASCII without space: '!' (0x21) to '~' (0x7E)\n        if ord(ch) < 0x21 or ord(ch) > 0x7E or ch in _BRACES:\n            raise ValueError(\n                f\"{field_name} must not contain spaces, newlines, non-printable characters, or braces\"\n            )\n\n\ndef _validate_driver_name(name: str) -> None:\n    \"\"\"Validate an upstream driver name.\n\n    The name should look like a typical Python distribution or package name,\n    following a simplified form of PEP 503 normalisation rules:\n\n    * start with a lowercase ASCII letter\n    * contain only lowercase letters, digits, hyphens and underscores\n\n    Examples of valid names: ``\"django-redis\"``, ``\"celery\"``, ``\"rq\"``.\n    \"\"\"\n\n    import re\n","sourceCodeStart":3,"sourceCodeEnd":39,"githubUrl":"https://github.com/redis/redis-py/blob/da03cdc7e8731092b13e395605c3c1fb2de25de1/redis/driver_info.py#L3-L39","documentation":"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.","triggerScenarios":"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.","commonSituations":"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.","solutions":["Strip/normalize the value to printable ASCII with no spaces or braces before passing it in.","Use a machine-style identifier (lowercase, hyphens) for the name and a clean semver for the version.","If you need a human label, keep it out of DriverInfo — it is only for CLIENT SETINFO, not display."],"exampleFix":"// before\ninfo.add_upstream_driver('My Redis Driver', '1.0.0\\n')\n\n// after\ninfo.add_upstream_driver('my-redis-driver', '1.0.0')","handlingStrategy":"validation","validationCode":"import re\n_VALID = re.compile(r'^[!-~]+$')\n_BRACES = set('()[]{}')\ndef clean_driver_value(v: str, field: str) -> str:\n    if not _VALID.match(v) or any(c in _BRACES for c in v):\n        raise ValueError(f'{field} has invalid chars: {v!r}')\n    return v\ninfo.add_upstream_driver(clean_driver_value(name,'name'), clean_driver_value(version,'version'))","typeGuard":"import re\n_BRACES = set('()[]{}')\ndef is_valid_driver_value(v) -> bool:\n    return (\n        isinstance(v, str)\n        and v != ''\n        and all(0x21 <= ord(c) <= 0x7E and c not in _BRACES for c in v)\n    )","tryCatchPattern":null,"preventionTips":["Use machine-style identifiers (lowercase, hyphens) and clean semver for version, never display text.","Strip whitespace/newlines from any version scraped from git or metadata before passing it in.","Validate values at config load time so invalid characters never reach DriverInfo.","Keep human-readable labels out of CLIENT SETINFO metadata."],"tags":["driver-info","client-setinfo","validation","valueerror"],"analyzedSha":"da03cdc7e8731092b13e395605c3c1fb2de25de1","analyzedAt":"2026-08-04T20:26:47.563Z","schemaVersion":2}