ContextActionService should warn when attempting to connect with existing action name

As a Roblox developer, it is difficult to debug situations where a ContextActionService binding is made with an action name that is already in use by another binding, because this will silently overwrite the already registered binding.


Consider the following two bits of hypothetical code that live in different scripts, where the first is executed before the second one:

-- This is bound first
game:GetService("ContextActionService"):BindAction(
    "ThisIsAlreadyUsed",
    function()
        print("Pressed F to pay respects")
    end,
    false,
    Enum.KeyCode.F
)
-- This is bound second
game:GetService("ContextActionService"):BindAction(
    "ThisIsAlreadyUsed", -- same identifier as above
    function()
        print("This will overwrite the previous action silently!")
    end,
    false,
    Enum.KeyCode.E
)

Both API members do not throw an error or a warning, they both go through, except the second call just silently overwrites the first binding because that action name is already in use. At this point, I would normally suggest pressing F to pay respects for the unfortunate death of the first binding, but clearly pressing F doesn’t actually trigger anything anymore.

It becomes especially interesting in cases when the order of execution of these segments of code is not deterministic. In one run, you might see one of the callbacks print and not the other, and vice versa on the next run. Imagine having to debug that without warnings/errors in a complex project!

Obviously, the F9 console can reveal that this action is already bound (however, if you accidentally use the same inputs in both bindings too, you cannot distinguish between the two in the list). However, throwing a warning instead of silently discarding the call would make this explicit, which would be great. This would have made me instantly realize that I was causing overlap with one of the control actions.

What especially confused me while debugging is that I was not thinking about the fact that the control scripts also register actions, and I happened to have one of the action names overlapping with those of the control scripts. The control script was overriding the action that I was binding without any sort of communication from the API in the output.

This should apply both to ContextActionService::BindAction and ContextActionService::BindActionAtPriority.


If Roblox is able to address this issue, it would improve my development experience, because it would be much easier to debug calls being seemingly ignored because of overlapping action names in ContextActionService.

7 Likes