MoEngage Web SDK · 30 September 2026

A second enquiry was overwriting the first person.

Two people enquiring from one browser produced one profile, carrying the wrong number. It was not a merge: the first person's history was relabelled with the second person's number, and they became unreachable under their own. This is what we changed, and how we know it works.

Reproduced 29 September 2026

One profile survived, and it had the wrong number on it

The first person's profile was relabelled with the second person's number. Their behaviour now sits under someone else's identity, and they are unreachable under their own.

Profiles expected

2

Two people, two mobile numbers, one browser

Profiles found

1

Labelled with the second person's number

History it carried

10 sessions

First seen 14 Sep, which is the first person's history

Reachable under their own number

0/2

One number now points at someone else, the other at nothing

The exposure is not unusual: a sales gallery tablet, a shared family device, or a channel partner entering several clients' enquiries in one sitting.

The cause

Documented behaviour, meeting a site with no login

This is not a fault in MoEngage. identifyUser updates the ID of the current user. Without an intervening logoutUser() there is no second profile for identifyUser to create. The SDK holds one bound identity per browser and rewrites it in place.

Rustomjee's website has no login, so there was no natural logout moment. There was never a moment at which to unbind one person before binding the next.

Two different meanings of "logout". Here it has nothing to do with a website login, and nothing to do with a visitor leaving. identifyUser binds the browser to a profile and logoutUser unbinds it. Firing logout when someone leaves would be wrong, because it would discard recognition of every returning visitor.

MoEngage's data-corruption warning is written for workspaces with the feature switched on. The damage was observed here regardless, so the finding and the fix hold either way.

Interactive

Submit some enquiries and watch what happens

One browser, three people. Turn the gate off to see the original behaviour, and on to see what is live now.

The browser

Identified as nobody yet

Submit an enquiry as:

Profiles in MoEngage

What the gate decided

  1. Nothing submitted yet.

The change

One tag, running just before we identify, deciding one of four things

The browser's stateWhat the gate doesUnbinds
Nothing to identify There is nothing to identify, so there is nothing to unbind. No
First enquiry in this browser The first enquiry in a browser. Identify runs on a clean slate. No
The same person again Deliberately does nothing. Unbinding a returning visitor would discard recognition of them. No
A different person The only state that calls logoutUser(). This is the case that used to relabel the first person. Yes

Only the last calls logoutUser(), and it is exactly the case that used to relabel the first person. The decision reads our own record of who this browser was last identified as, because we are the ones who set it. MoEngage's own store is read as a cross-check, which matters for browsers bound before this change shipped.

Evidence

Four checks, none resting on the others

1. Three numbers produced three distinct profiles

Compare MoEngage IDs, not session counts. The same id would mean the same underlying profile, so three distinct ids is what proves a genuine split rather than a rename.

EnquiryNumberMoEngage profile
Phone A91XXXXXX91226aa7bc54
Phone B91XXXXXX15426abc159e
Phone C91XXXXXX00526abc2022

Phone A 91XXXXXX9122

Before

MoEngage ID 6aa7bc54

After

unchanged, and now carries a User Logout event

Phone B 91XXXXXX1542

Before

no profile at all

After

MoEngage ID 6abc159e

2. MoEngage's own User Logout event appeared

User Logout is MoEngage's own derived event on Web and cannot be produced from our side. Its absence from both Activity Info exports of 29 September is what proved the first attempt had failed; its presence is what proves the second one worked.

3. Each new profile is a first session

Each new profile's lead_submitted carries First Session: true. A relabelled profile would carry the previous person's history and read false. Confirmed on Contact Us and the project enquiry modal.

4. The same result on the published container, not only in preview

Our own record and MoEngage's own store independently name the same bound identity, on the published container rather than in Preview.

our own record   91XXXXXX0052

MoEngage's store 91XXXXXX0052 (key uid)

decision        logout, unbind called: yes

And it is safe to run repeatedly

The gate runs 4 times during a single enquiry, because of how the tags chain. Only the first run can log out. It writes the record immediately, so every later run reads same-person.

  1. Run bound to Phone B submitting Phone C logout
  2. Run bound to Phone C submitting Phone C same-person
  3. then 2 more, all the same person, all standing down

Stated, not hidden

What this does not cover

A browser MoEngage had already bound before the gate shipped carries no record of ours. If MoEngage's own store also comes back empty on such a browser, its first submission will not log out, so one relabel can still happen once per such browser.

Measured since: getUserIdentities() does return the bound number on such a browser, so it is covered by the fallback on its own. That matters because on publish day every returning visitor is one of these browsers.

Worst case: no logout, which is the behaviour before this change rather than a new harm.

Over to MoEngage

What we need confirmed

1

Confirm the approach

Confirm that calling logoutUser() before identifyUser(), only when the number submitted differs from the one that browser is already identified as, is the right primitive for a site with no login, and that nothing further is required.

2

A correction for the documentation

getUserIdentities() is documented as the asynchronous getter. It returns synchronously. Building to the documented behaviour is what made our first attempt fail silently, and it will cost the next customer the same cycle.

3

Identity Resolution on the LIVE workspace

Identity Resolution is configured per workspace. We have access to TEST only, so nothing observed there predicts LIVE. Please confirm the LIVE setting before the switch rather than at it.

The change is published as version 3, dated 30 September 2026. It contained exactly 2 changes. The identity gate was added, and Identify User was rechained behind it. No triggers, no variables, no other tags. Republish v2 from the Versions list. The container environment remains TEST, so this is not the same as going live.