{"record":{"id":"0ad827c2eca9ede1","repo":"Textualize/textual","slug":"input-type-must-be-one-of-friendly-list-restrict","errorCode":null,"errorMessage":"Input type must be one of {friendly_list(_RESTRICT_TYPES.keys())}; not {type!r}","messagePattern":"Input type must be one of (.+?); not (.+?)","errorType":"exception","errorClass":"ValueError","httpStatus":null,"severity":"error","filePath":"src/textual/widgets/_input.py","lineNumber":441,"sourceCode":"        )\n        \"\"\"Set with event names to do input validation on.\n\n        Validation can only be performed on blur, on input changes and on input submission.\n\n        Example:\n            This creates an `Input` widget that only gets validated when the value\n            is submitted explicitly:\n\n            ```py\n            input = Input(validate_on=[\"submitted\"])\n            ```\n        \"\"\"\n        self._reactive_valid_empty = valid_empty\n        self._valid = True\n\n        self.restrict = restrict\n        if type not in _RESTRICT_TYPES:\n            raise ValueError(\n                f\"Input type must be one of {friendly_list(_RESTRICT_TYPES.keys())}; not {type!r}\"\n            )\n        self.type = type\n        self.max_length = max_length\n        if not self.validators:\n            from textual.validation import Integer, Number\n\n            if self.type == \"integer\":\n                self.validators.append(Integer())\n            elif self.type == \"number\":\n                self.validators.append(Number())\n\n        self._selecting = False\n        \"\"\"True if the user is selecting text with the mouse.\"\"\"\n\n        self._initial_value = True\n        \"\"\"Indicates if the value has been set for the first time yet.\"\"\"\n        if value is not None:","sourceCodeStart":423,"sourceCodeEnd":459,"githubUrl":"https://github.com/Textualize/textual/blob/06dbeef4bb70fb718236aa418ed658ef4667a126/src/textual/widgets/_input.py#L423-L459","documentation":"A ValueError raised in Input.__init__ when the type argument is not one of the keys of _RESTRICT_TYPES (typically 'text', 'integer', 'number', 'password' — the exact set depends on the Textual version). Input uses this enum to configure input filtering/validation, so unknown strings are rejected at construction.","triggerScenarios":"Passing type='int' or type='Integer' (wrong casing/spelling) to Input; passing a custom string not in _RESTRICT_TYPES; upgrading Textual where the allowed set changed.","commonSituations":"Copy-pasting Input(type=...) snippets from older docs/examples; dynamic type selection from config where an invalid value slips in; typos like 'interger'.","solutions":["Use an exact allowed literal, e.g. Input(type='integer').","Validate config-driven values against the allowed set before constructing Input.","Check the installed version's _RESTRICT_TYPES keys (from textual.widgets._input import _RESTRICT_TYPES) when unsure.","Omit type= entirely for plain text input."],"exampleFix":"# before\nfield = Input(type='int')\n\n# after\nfield = Input(type='integer')","handlingStrategy":"validation","validationCode":"from textual.widgets._input import _RESTRICT_TYPES\nassert input_type in _RESTRICT_TYPES, f'bad type {input_type!r}'\nInput(type=input_type)","typeGuard":"from textual.widgets._input import _RESTRICT_TYPES\n\ndef is_valid_input_type(t: object) -> bool:\n    return isinstance(t, str) and t in _RESTRICT_TYPES","tryCatchPattern":null,"preventionTips":["Use exact literals like 'integer', 'number', 'text', 'password'","Validate config-driven type strings against _RESTRICT_TYPES","Check docs for the installed Textual version"],"tags":["textual","input","value-error","enum-validation"],"backgroundTag":"invalid-enum-value","analyzedSha":"06dbeef4bb70fb718236aa418ed658ef4667a126","analyzedAt":"2026-08-27T02:36:57.214Z","schemaVersion":2},"datasetVersion":"2026-08-27T03:17:27.898Z"}