reflex-dev/reflex · error · ValueError

DebounceInput child requires an on_change handler

Error message

DebounceInput child requires an on_change handler

What it means

DebounceInput works by intercepting the child's on_change event and delaying it. If the wrapped input has no on_change handler, there is nothing to debounce, so creation fails.

Source

Thrown at packages/reflex-components-core/src/reflex_components_core/core/debounce.py:89

        Returns:
            The DebounceInput component.

        Raises:
            RuntimeError: unless exactly one child element is provided.
            ValueError: if the child element does not have an on_change handler.
        """
        if len(children) != 1:
            msg = (
                "Provide a single child for DebounceInput, such as rx.input() or "
                "rx.text_area()"
            )
            raise RuntimeError(msg)

        child = children[0]
        if "on_change" not in child.event_triggers:
            msg = "DebounceInput child requires an on_change handler"
            raise ValueError(msg)

        # Carry known props and event_triggers from the child.
        props_from_child = {
            p: getattr(child, p)
            for p in cls.get_props()
            if getattr(child, p, None) is not None
        }
        props[EventTriggers.ON_CHANGE] = child.event_triggers.pop(
            EventTriggers.ON_CHANGE
        )
        props = {**props_from_child, **props}

        # Carry all other child props directly via custom_attrs
        other_props = {
            p: getattr(child, p)
            for p in child.get_props()
            if p not in props_from_child and getattr(child, p) is not None
        }

View on GitHub (pinned to 45b8ed5ab7)

Solutions

  1. Add an on_change handler to the child input: rx.debounce_input(rx.input(on_change=State.set_query))
  2. If you don't need debouncing, use the plain input without rx.debounce_input

Example fix

// before
rx.debounce_input(rx.input(placeholder='Search'))
// after
rx.debounce_input(rx.input(placeholder='Search', on_change=State.set_query), delay_ms=300)
Defensive patterns

Strategy: validation

Validate before calling

child = rx.input(value=State.q, on_change=State.set_q)
rx.debounce_input(child)

Prevention

When it happens

Trigger: `rx.debounce_input(rx.input(placeholder='search'))` with no on_change; wrapping a read-only or display-only input.

Common situations: Building a search box but wiring the handler later; copy-pasting an input element into debounce_input without its event props.

Related errors


AI-assisted analysis of reflex-dev/reflex@45b8ed5ab7 (2026-08-28). Data as JSON: /api/errors/74ca7bcd17b4c02d. Report an issue: GitHub.