Search code examples
discorddiscord.pydiscord-buttons

Discord Buttons "Interaction Failed": TypeError: MyView.on_button_click() missing 1 required positional argument: 'button' / 'interaction'


I have been trying to make buttons bassed off of a list that the user inputs but I keep getting this error that boggles my mind. The error occurs when I press the buttons. The buttons are made but when I press one of the buttons i keep getting the infamous "interaction failed".

Error: TypeError: MyView.on_button_click() missing 1 required positional argument: 'button'

Code:

class MyView(View):
        def __init__(self, options):
                super().__init__()
                self.options = options
                
                for option in options:
                        button = Button(label=option, custom_id=option)
                        button.callback = self.on_button_click  
                        self.add_item(button) 
                        

        async def on_button_click(self, interaction: discord.Interaction, button: discord.ui.Button):
                await interaction.response.send_message(f"You clicked: {button.label}")

The reason why this boggles my mind is because when I try and switch the on on_button_click to:async def on_button_click(self, button: discord.ui.Button, interaction: discord.Interaction): I will get the error TypeError: MyView.on_button_click() missing 1 required positional argument: 'interaction' If you know how to fix this or what might be wrong please let me know. thanks...

I tried switching the foration of the def function to no avail. I also tried adding discord.Interactions and discord.ui.Buttons to the class arguments.


Solution

  • The docs clearly say that the Button.callback function should only take one argument, interaction:

    class MyView(View):
        def __init__(self, options):
            super().__init__()
            self.options = options
                    
            for option in options:
                button = Button(label=option, custom_id=option)
                button.callback = self.on_button_click  
                self.add_item(button) 
                            
    
        async def on_button_click(self, interaction: discord.Interaction):
            ...
    

    However, you cannot access the Button.label attribute now, to fix that you can simply create your own custom button:

    class MyButton(Button):
        async def callback(self, interaction: discord.Interaction):
            await interaction.response.send_message(f"You clicked {self.label}")
    
    
    class MyView(View):
        def __init__(self, options):
            super().__init__()
    
            self.options = options
    
            for option in options:
                button = MyButton(label=option, custom_id=option)
                self.add_item(button)