One person, two JSM customer accounts: what actually clears the duplicate after an email change
One person, two JSM customer accounts: what actually clears the duplicate after an email change Key takeaways - JSM has no in-place email change for a customer. Atlassian's own admin page lets you edit the full name and nothing else, which is why editing the customer record never touches the address. - Removing the customer from the service project cannot fix it. I measured two duplicate accounts that belonged to zero service desks and still filled the user picker. - An empty result from the find-their-tickets JQL is not evidence. The endpoint that used to error is gone (HTTP 410), and the one that replaced it returns a silent empty list for an account that does not exist. - Reassigning the reporter can fail with a 400 that blames the screen. I measured the field present on the edit screen, which rules that explanation out and leaves the Modify Reporter permission as the documented cause. - There is still no way to merge two Atlassian accounts. ID-240 is Future Consideration with 2,839 votes, open since 2015. An admin on the Atlassian Community described this in three sentences, and I have not seen it put better since: One of our customers got a new email address, the domain changed (aaa.com to bbb.com). We updated the customer record within the respective space. Now, when we create a new issue and search for the user in the reporter field, it appears twice, with both old and new email domain. How can this be fixed. We don't want the old address to appear obviously. Every clause there is a step in the same trap. The customer record was updated, and updating it did nothing to the email. The picker shows two rows because there really are two accounts. And the thing most admins reach for next - taking the old one out of the project - is the one action that provably cannot help. I answered that thread in July. What follows is the part I could not fit into a forum reply: the mechanism, and the measurements I ran on my own test site afterwards to check the advice everyone gives for this - including my own. Most of it held up. Two steps on the fix path have a trap in them that nothing warns you about, and one route that solves the problem outright never came up on the thread at all. Why the record edit did nothing Jira Service Management has no in-place email change for a customer. That is not a gap in the UI you can route around with an API call - it is the shape of the product. Every clause of the original question is a step in the same trap. Editing the record never touched the email. Atlassian's admin documentation for portal-only customers is unusually clear on this if you read what it does not offer. The page covering what an admin may change is titled "Edit name for portal-only customers", and full name is the only field it exposes. There is no email field anywhere in that flow. So an admin who opens the customer record, corrects what they can see, and saves has genuinely done everything the interface allows - and the address is untouched. Meanwhile the person on the other end has a new mailbox. When they next arrive at the portal on bbb.com , that address does not match any existing account, so it becomes one. Now there are two customer records for one human being, and the reporter field is doing exactly what it is supposed to do by showing you both. I want to be exact about what I proved and what I am repeating. I did not reproduce the sign-up half - I created both accounts directly, which lands you in the same end state without waiting for a real person to log in twice. The causal half, that a new address produces a new account, is the documented behaviour of customer account creation and is what the Community Champion on that thread described from their own experience. Treat the mechanism as well-attested; treat the end state as measured, because that part I ran. Telling the two apart in one call Before fixing anything, you need to know which of the two rows is which. The picker shows the same display name twice and distinguishes them only by the email suffix, which is fine until you are holding two account IDs in a script and cannot remember which is the survivor. The discriminator is accountType , and it is on every user record: curl -s -u "$EMAIL:$TOKEN" \ --get --data-urlencode "accountId=$ACCOUNT_ID" \ "https://your-site.atlassian.net/rest/api/3/user" A portal-only customer comes back as "accountType": "customer" . A full Atlassian account comes back as "atlassian" . That distinction matters more than it looks, because it decides which of the fixes below is even available to you. There is also an eyeball tell. Every portal-only account I created carried an account ID in the form qm: : , while ordinary Atlassian accounts on the same site are the familiar : . Atlassian does not document that format, so I would not build a script on it - but when you are staring at two IDs in a terminal, the qm: prefix tells you instantly which one is the portal-only record. The trap: removing them from the project This is the step that costs people an afternoon, and it is worth being blunt about why. Removing a customer from a service project unlinks them from that project, which is all Atlassian's own page for that action claims it does. The account itself lives at site level, and the user picker reads from site level, so the row you just removed keeps appearing. I measured the strongest version of this. On my test site I created two customer accounts with the same display name on different domains, and I never added either of them to a service desk - they belonged to zero service projects. Then I queried the picker: curl -s -u "$EMAIL:$TOKEN" \ "https://your-site.atlassian.net/rest/api/3/user/picker?query=Dana&maxResults=20" { "total": 2, "users": [ { "html": " Dana Rowe - dana .r***@lz-oldco.example" }, { "html": " Dana Rowe - dana .r***@lz-newco.example" } ] } Two rows, from accounts with no project membership at all. If zero service desks is not enough to keep an account out of the picker, then removing it from one service desk was never going to be either. Project membership and identity are different layers, and the picker reads the lower one. This is also why "I removed them and it still shows" is not a bug report. The removal worked. It simply was not the operation that governs what the picker returns. That measurement was on the REST endpoint behind the reporter field rather than on the rendered agent view, so treat it as a statement about the API. It matched what the original thread reported from the UI. The route the thread never mentioned Neither answer on that thread named the option Atlassian actually documents for this situation, and it is the cheapest fix available - provided you catch it in time. Atlassian's KB "Changing a Customer's Email Address in JSM Cloud" (Cloud only, last updated 25 September 2025, read 15 August 2026) gives two methods. The second is Migrate to Atlassian account, from Atlassian Administration under Products, your site, Jira Service Management, Portal customers, then the three-dot menu on the customer. Once the customer holds a real Atlassian account, they manage their own email at id.atlassian.com and the whole problem stops being yours. The migration page is worth reading before you click, because it carries three facts that decide whether you want this: | Fact | Consequence | |---|---| | It deactivates the portal-only profile and migrates their requests to the new account | The history follows them, which is the point | | Processing takes up to 10 minutes | Not instant, so do not queue a second action behind it | | The old profile stays visible as Inactive and you cannot un-migrate it | One-way door | It also requires an organisation admin in the centralised experience, and it is not available in the Atlassian Government environment. Here is the honest limitation, and it is the one that decides whether this route helps you: none of those pages state what happens if an Atlassian account already exists on the target address. That is a documentation silence, not a documented failure - I am not going to tell you it breaks, because I could not test it without a second organisation. What I can say is that the collision is exactly the situation the thread was in. The customer had already signed in on bbb.com , so that address was already taken by the second account. Migration is the fix for the window before the duplicate exists. Once you have two, you are in the cleanup below. Cleanup, and the two traps inside it The standard cleanup is the KB's Method 1: move the old account's tickets onto the new account, then get rid of the old account. Both halves have a trap. Trap one: an empty JQL result is not evidence The KB tells you to find the old account's tickets with a reporter query. That advice is correct - I tested both forms and both work, including for a portal-only customer: reporter = "da*******@lz-oldco.example" reporter = "qm: : " Both returned the ticket I had planted. So far so good. The problem is what happens when the query does not match. Atlassian removed the old search endpoint. GET /rest/api/3/search now answers with HTTP 410 and a pointer to CHANGE-2046 - the same pattern as Bitbucket answering a dead credential with a 410 rather than a useful error, where the status code is the whole message and the tooling around it has not caught up. The replacement, /rest/api/3/search/jql , does not validate the user at all: curl -s -u "$EMAIL:$TOKEN" --get \ --data-urlencode 'jql=reporter = "nob**********@nonexistent.example"' \ "https://your-site.atlassian.net/rest/api/3/search/jql" {"issues":[],"isLast":true} No error. No warning. I also ran that query through POST /rest/api/3/jql/parse?validation=strict , which is the endpoint whose entire job is to tell you a query is wrong, and it came back with an empty error list and an empty warning list. So a clean empty list means one of two things and gives you no way to tell them apart: the account has no tickets, or the string you
Comments
No comments yet. Start the discussion.