Exclamation mark and special characters in usernames


We’re in progress of moving a big community on Discourse from vb3.
Many usernames - around 1.200 - do contain the exclamation mark “!” and I couldn’t find any option to re-enable it.
We already enabled “unicode usernames” to no avail.
Is there any ready solution for this issue?

Thank you!

1 Like

No. Changing legal characters in usernames is not really an option. I think they’ll have to have less exciting usernames.

Wow, seems like quite the oversight…is any technical explanation for this? Our would we be able to sort this with a plugin or a fork?

I didn’t make the decision, but there are plenty of systems for which a ! isn’t a valid character for a username. It’s a good bet that if you did try to allow it in a plugin (or a fork, which would be a very, very bad idea if you ever want to upgrade Discourse again), it will be hard.

The ! has special meanings in a bunch of contexts and I suspect that if you just change the username validator a bunch of other stuff will break.

I understand. It’s something that should be addressed though. All other BB solutions allow that char in the username and it’s common in gaming communities. Username and user ID should be kept as separate entities as not to have such limitations. We have around 95.000 members and contacting 1.200 of them to change their username is going to be a real PITA. Thanks for the help anyway!

1 Like

I’ve done dozens, maybe over a hundred imports. I pay close attention to people asking about imports here. This is the first time I remember anyone complaining about it.

You can tell everyone to try both their username and their email address (a bunch of them won’t know that either). It is a good bet that you have some other usernames that changed.

This will give you all of the usernames that changed:

UserCustomField.where(name: 'import_username').pluck(:value)

I found a couple of topics:

It’s probably going to be alot more than just exclamation marks. Seems such a strange limitation, since you can use those characters anywhere else.

Anyway, thank you for your help.

1 Like

It’s worth pointing out that names and usernames aren’t the same thing. Usernames are used in URL paths, for example:


An exclamation mark isn’t a valid character in a URL, while characters such as ? & have special purposes in URL structure and therefore also can’t be part of a username. This isn’t specific to Discourse, any system which uses the username in the URL structure has to respect this.

A username can’t contain an exclamation mark, but the name can, which you can prioritize in the UI.


makes perfect sense @Stephen, thanks for clarifying.

I think we could just alter the import script to do something like:

username_original = username
username = @htmlentities.decode(user["username"]).strip

          id: user["userid"],
          name: username_original,
          username: username,
          password: password,

And in the discourse setting enable the priority for the user “name”, if it’s present, over the username.


In addition to this, usernames are meant to be used in @mentions, and so the expectation is that usernames will be straightfoward and easy to type; that’s why we only allow ASCII characters by default (though that can be expanded to unicode by the unicode_usernames setting, though still no punctuation).

Note that that migration script uses the non bulk migration script base class, which does this with each user record generated by the method you linked:

which strips any invalid characters from usernames.

There are many places in the code that assume certain things about usernames (@mention parsing, changing usernames, etc), which is the reason why we enforce these restrictions.

Like Stephen says, usernames are not the place to show user personality; the name and flair fields are :slight_smile:


There’s still quite a few fringe cases that are difficult to manage with it being this way.
Names are non-unique, if we give priority in the layout to the name you can imagine how that would go in a message board full of immature teenagers that game and troll all day :slight_smile:

It’s perfectly fine to say that it might be a low priority issue, still it’s something that could clearly use some thought and work and for sure not a “feature” or something that gives an advantage over being able to choose an unique name without strong limits like any other bb software that’s been around.

1 Like

If the user is pfaffman! the URL would usually be:
At least, any other CMS I’ve ever worked on worked like this

1 Like

Oh, cool! Prior art. :+1:

Would you mind sharing some of the open source CMS projects you’ve used? We can take a look at them and see how they handle the permalinks and user references, learn from their efforts. :slight_smile:

Although… I wonder if Content Management Systems is the exact same bucket as Community Forums? :thinking:

Does “vb3” refer to vBulletin?


Also, the mention of special characters being encoded is not something unique of CMS, it’s just standard encoding: Percent-encoding - MDN Web Docs Glossary: Definitions of Web-related terms | MDN

1 Like

But then how would we mention folks, @Crius?!

:point_up: :smiley: :point_down:

But then how would we mention folks, @Crius?!

Would we type @maiki&#33, to mention someone with maiki! as a username? :thinking: How does it work in vBulletin?

1 Like

vBulletin 3 doesn’t have that features and vBulletin 5… I’ve no idea if it even has the feature as it’s a software that clearly has been left behind in terms of modern features.

When you ping someone on discourse an auto-suggest comes up. No need to worry about having to type the full nickname.
Edit: Eventually it means having the suggest decode the list of usernames before suggesting it if you really want, or encode the input (the user writing the partial) so that it can search for the username appropriately.

I mean, we can argue about how much work and effort it takes, but not “if” it’s possible.

In any case, I don’t know if it’s just the media being a bad at passing the mood but all these recent replies felt kinda “hostile”. People comes on meta.discourse to ask for help and suggest things to improve. If you don’t agree you can just ignore the thread and move on.

Also, I forgot to add. If PRs are open for discourse, I can try and work on it in a fork and open a PR. Granted I’m not a ruby developer but I’ve several years of working as software engineer / platform engineer. I’ll be glad to try and contribute :slight_smile:


Just updating for posterity, ! are not a thing forbidden in URLs as mentioned above. I don’t know from where this notion came through.

However, Ruby seems to be using ? and ! in their functions which is a weird thing to be honest (at least in my 20+ years of software engineering) but each language has its own things :slight_smile:

Which might hint at why ! is forbidden. I’ll have to dig deeper into discourse source code to understand if this was a specific issue that couldn’t be solved or just something that overzealously prohibited to avoid potential issues between usernames and ruby going crazy in some edge cases.