python-telegram-bot/python-telegram-bot · error · ValueError

You can not filter for users and include anonymous reactions

Error message

You can not filter for users and include anonymous reactions. Set `message_reaction_types` to MESSAGE_REACTION_UPDATED.

What it means

MessageReactionHandler can filter by users, but anonymous reactions ( MESSAGE_REACTION and MESSAGE_REACTION_COUNT_UPDATED reaction types) have no user attached. Filtering by user_id/user_username while including those anonymous reaction types is contradictory, so __init__ raises ValueError immediately.

Source

Thrown at src/telegram/ext/_handlers/messagereactionhandler.py:131

        self: "MessageReactionHandler[CCT, RT]",
        callback: HandlerCallback[Update, CCT, RT],
        chat_id: SCT[int] | None = None,
        chat_username: SCT[str] | None = None,
        user_id: SCT[int] | None = None,
        user_username: SCT[str] | None = None,
        message_reaction_types: int = MESSAGE_REACTION,
        block: DVType[bool] = DEFAULT_TRUE,
    ):
        super().__init__(callback, block=block)
        self.message_reaction_types: int = message_reaction_types

        self._chat_ids = parse_chat_id(chat_id)
        self._chat_usernames = parse_username(chat_username)
        if (user_id or user_username) and message_reaction_types in (
            self.MESSAGE_REACTION,
            self.MESSAGE_REACTION_COUNT_UPDATED,
        ):
            raise ValueError(
                "You can not filter for users and include anonymous reactions. Set "
                "`message_reaction_types` to MESSAGE_REACTION_UPDATED."
            )
        self._user_ids = parse_chat_id(user_id)
        self._user_usernames = parse_username(user_username)

    def check_update(self, update: object) -> bool:
        """Determines whether an update should be passed to this handler's :attr:`callback`.

        Args:
            update (:class:`telegram.Update` | :obj:`object`): Incoming update.

        Returns:
            :obj:`bool`

        """
        if not isinstance(update, Update):
            return False

View on GitHub (pinned to d3b69d2e9f)

Solutions

  1. Set message_reaction_types to MessageReactionHandler.MESSAGE_REACTION_UPDATED (the non-anonymous type) when filtering by user
  2. Or drop the user_id/user_username arguments to keep anonymous reactions
  3. If you need both, register two handlers: one user-filtered for MESSAGE_REACTION_UPDATED and one unfiltered for anonymous types

Example fix

# before
MessageReactionHandler(
    callback,
    user_id=12345,
    message_reaction_types=MessageReactionHandler.ALL_TYPES,
)

# after
MessageReactionHandler(
    callback,
    user_id=12345,
    message_reaction_types=MessageReactionHandler.MESSAGE_REACTION_UPDATED,
)
Defensive patterns

Strategy: validation

Validate before calling

from telegram.ext import MessageReactionHandler
anonymous = (MessageReactionHandler.MESSAGE_REACTION, MessageReactionHandler.MESSAGE_REACTION_COUNT_UPDATED)
def is_valid(user_id, user_username, types):
    has_user = bool(user_id or user_username)
    included = types in anonymous or (isinstance(types, (list, tuple, set)) and any(t in anonymous for t in types))
    return not (has_user and included)

Prevention

When it happens

Trigger: MessageReactionHandler(user_id=..., user_username=..., message_reaction_types=MessageReactionHandler.MESSAGE_REACTION) — or MESSAGE_REACTION_COUNT_UPDATED — or an iterable containing them. Any user filter combined with anonymous reaction types raises at construction time.

Common situations: Wanting to track all reactions including anonymous ones while also restricting to a specific user. Developers often pass message_reaction_types=MessageReactionHandler.ALL_TYPES together with user_id, which includes the anonymous types.

Related errors


AI-assisted analysis of python-telegram-bot/python-telegram-bot@d3b69d2e9f (2026-08-28). Data as JSON: /api/errors/498f8421c41a159f. Report an issue: GitHub.