Join GitHub today
GitHub is home to over 40 million developers working together to host and review code, manage projects, and build software together.Sign up
Role and user mentions are returned out of order #2669
Please describe the problem you are having in as much detail as possible:
User and role mentions are returned out of order in which they appear in a message. They always appear in the same, fixed order (which appears to be by role/user creation date, oldest first). It's worth noting that channel mentions do always appear in the correct order.
Include a reproducible code sample here, if possible:
For a simple (albeit silly) pseudocode demo, here are two messages that mention 3 channels, 3 roles, and 3 users in a different order...
A similar issue was raised (and fixed) in Jan 2016 (#166), but appeared to resurface in late 2017.
As it stands today, this issue is caused by relying on the raw data coming back from the Discord API. Inspecting the raw return data from Discord shows the mentions coming back ordered by user/role creation date.
This can be dangerous behavior, IMO. Storing in a Collection (Map) means we should be able to rely on them being returned in insertion order. In the context of a message, the implication is that it would be the order in which they were mentioned.
In Discord.JS's own docs, an example recommends using
But let's say someone sets up a command with the syntax
The question is -- is this something the Discord.js project would be willing to fix (parsing the message for those mentions on its own)? Or would we have to rely on Discord to make that change? (Based on my past experience with them and their massive bug backlog, I'd guess the chances of them changing it are slim to none.)
If the latter, then this completely rules out using any commands in which the order of mentions would be significant -- and in that case, the docs should be updated to warn users not to rely on it.
Channel mentions are artificially constructed from the message content; we rely on Discord to provide data on which users and roles are mentioned. In this case, it seems very likely that Discord is sending data that is out of order. It is possible to correct this by simply generating all mentions from the message content, but I'm not sure that's a design change we would like to make.
Personally I have always been a fan of manually parsing message content to ensure that it meets command requirements. Using the mentions object is further complicated by bots that support mention prefix (which all bots should). Personally, I would prefer to see the docs updated to encourage parsing the message content manually.
I'm not entirely sure what "position" you could be referring to. The position of roles in the guild is entirely irrelevant, and mentions are supplied by the API as an array of IDs (in the case of roles) or base objects (in the case of users). Neither of these provide a mention order outside of the array itself, which seems to be incorrect.
From the Discord.js homepage:
discord.js is a powerful node.js module that allows you to interact with the Discord API very easily. It takes a much more object-oriented approach than most other JS Discord libraries, making your bot's code significantly tidier and easier to comprehend. Usability, consistency, and performance are key focuses of discord.js
I don't think anyone would disagree that returning mentions unexpectedly out of order is harmful to usability and consistency. And asking people to parse messages on their own if they want it to work properly because they can't rely on one of the objects the library returns certainly makes the library less "easy" to use.
Correct me if I'm wrong, but I think performance would be the only reason to consider not fixing this issue?
And from a design perspective -- if we're already parsing the messages to artificially construct channel mentions, is it that big a departure to also do the same for roles and users? Especially when the library has done that before in the recent past?
Discord.js just uses the list of mentions provided by the API. Neither the API documentation nor our own documentation ever list the properties as ordered in any specific way. Furthermore, they're placed in a Collection (a Map), which, while technically ordered, relying on them being so is typically not recommended.
Nobody should be relying on the
The performance impact of running two additional regular expressions against every single message received by a bot would be significant, and is not something we want to do for data that is already provided by the API anyways.
Here's another fun reason you absolutely should not be relying on a simple list of mentions for your arguments: If someone mentions your bot with a command (which every bot should support, no exceptions), i.e.
This may be true -- but apparently there is confusion even among the maintainers as to the use of these collections which I will reference again here (a particularly dangerous example in this case, since it can kick the wrong user from the server).
Library users are going to expect the collection ordering to work as advertised in the docs. I'd suggest that this issue remain open until any examples referencing mentions.[users|roles].first() are rewritten to manually parse the mentions as discussed above. It would also be beneficial to put a warning on the users and roles pages to let people know that