Textualize/rich · warning · InvalidResponse

[prompt.invalid]Please enter a valid value

Error message

[prompt.invalid]Please enter a valid value

What it means

Prompt.process_response() converts the user's typed string via self.response_type (e.g. int for IntPrompt). If that constructor raises ValueError — the input can't be parsed — rich raises InvalidResponse with validate_error_message ('[prompt.invalid]Please enter a valid value'). It is an internal control-flow exception caught by the ask loop, which re-prompts; it only escapes if you call process_response directly.

Source

Thrown at rich/prompt.py:243

        return value.strip().lower() in [choice.lower() for choice in self.choices]

    def process_response(self, value: str) -> PromptType:
        """Process response from user, convert to prompt type.

        Args:
            value (str): String typed by user.

        Raises:
            InvalidResponse: If ``value`` is invalid.

        Returns:
            PromptType: The value to be returned from ask method.
        """
        value = value.strip()
        try:
            return_value: PromptType = self.response_type(value)
        except ValueError:
            raise InvalidResponse(self.validate_error_message)

        if self.choices is not None:
            if not self.check_choice(value):
                raise InvalidResponse(self.illegal_choice_message)

            if not self.case_sensitive:
                # return the original choice, not the lower case version
                return_value = self.response_type(
                    self.choices[
                        [choice.lower() for choice in self.choices].index(value.lower())
                    ]
                )
        return return_value

    def on_validate_error(self, value: str, error: InvalidResponse) -> None:
        """Called to handle validation error.

        Args:

View on GitHub (pinned to 9d8f9a372c)

Solutions

  1. Rely on Prompt.ask/IntPrompt.ask — the built-in loop catches InvalidResponse and re-prompts automatically; no action needed.
  2. If calling process_response yourself, wrap it in try/except InvalidResponse and loop until valid.
  3. For custom response_type, ensure its constructor raises ValueError (the only type caught) on bad input, or override process_response.

Example fix

# before
value = prompt.process_response(raw)  # InvalidResponse escapes

# after
from rich.prompt import InvalidResponse
while True:
    try:
        value = prompt.process_response(input('> '))
        break
    except InvalidResponse:
        print('try again')
Defensive patterns

Strategy: try-catch

Try / catch

from rich.prompt import InvalidResponse, IntPrompt
# ask() already retries; only needed for direct process_response:
try:
    val = IntPrompt.process_response(prompt, raw)
except InvalidResponse:
    val = None  # re-ask

Prevention

When it happens

Trigger: IntPrompt.ask('Enter a number') and the user types 'abc'; Prompt(response_type=int) with non-numeric input; calling prompt.process_response('not-an-int') outside the ask loop. Any response_type whose constructor raises ValueError on the raw string.

Common situations: Interactive CLIs validated with IntPrompt/FloatPrompt where users paste text or leave stray characters; overriding process_response or calling it directly (bypassing ask's retry loop); a custom response_type with a constructor that raises ValueError for valid-looking input.

Related errors


AI-assisted analysis of Textualize/rich@9d8f9a372c (2026-08-15). Data as JSON: /api/errors/6da4caa3f977c7ca. Report an issue: GitHub.