Reset multipassIdentifier to null, but it still get error

hi.

I use the multipass url to log in users, but for some users, the multipassIdentifier is set incorrectly and has not been initialized on our side.

I used the API to set the multipassIdentifier to null, but the login via the multipass url still failed, with the error message “The given email address is already used by another customer (with a different Multipass identifier)”.

Since you provide an API for changing the multipassIdentifier, does setting the Identifier to null mean that the user has not set an identifier?

The error step.

  1. Use api to update multipassIdentifier , and set it A(which is wrong identifier).
  2. Use api to update multipassIdentifier , and set it null.
  3. User regist a new identifier and log in by multipass url(which identifier is B).
  4. User get error ‘The given email address is already used by another customer (with a different Multipass identifier)‘

Which i want:

  1. Use api to update multipassIdentifier , and set it A(which is wrong identifier).
  2. Use api to update multipassIdentifier , and set it null.
  3. User regist a new identifier and log in by multipass url(which identifier is B).
  4. User log in success and the multipassIdentifier set to B.

Hi @quanah_gong!

I tested this on my dev store and the API behavior looks correct—setting multipassIdentifier to null via customerUpdate does clear the field to null in the response. The interesting bit is your error happens during the actual Multipass login flow, not when you’re updating via the API.

This suggests there might be a disconnect between how the Customer API stores the value versus how the Multipass authentication validates it when someone tries to log in. I’ve seen similar reports internally where the API shows null but the Multipass login still acts like there’s an identifier set.

Can you share a few details so I can dig deeper?

  • What API version are you using?
  • The exact mutation you’re running to set it to null (incl. variables, redacted as required)
  • The x-request-id from the response when you set it to null

Also just to confirm the flow: you’re setting it to null via the API, then generating a fresh Multipass token with identifier “B”, redirecting to /account/login/multipass/{token}, and that’s where you see the “email already used” error?

The Multipass docs mention you can use the Customer API to update the multipass_identifier, and since the field is nullable, setting it to null should clear it. If the Multipass login isn’t respecting that, sounds like something we would need to investigate internally.

  • The GraphQL API version used is 2025-04, the updated GraphQL API version for multipassIdentifier uses 2025-10 and the obsolete API (admin/app/2023-10/customers/xxx. json), but both APIs have the same issue.
  • We manually call Api to update the multipassIdentifier. One of the requestId: 86ec1312-91dc-46be-bb93-d2027ca86e5d-1762480956.
  • When redirecting to /account/login/multipass/{token}, the web show that message(this is what users can see), just like this:

  • the test account info as below:
{
    "customer": {
        "id": "gid://shopify/Customer/9491196215480",
        "createdAt": "2025-11-06T03:15:13Z",
        "multipassIdentifier": null,
        "email": "QuanahTest@vesync.com",
        "events": {},
        "displayName": "Mu Dian",
        "orders": {}
    }
}

Hey @quanah_gong, good catch on this. I’ve reproduced what you’re seeing on a test store, and there’s definitely something off with how the Multipass validation handles the null state.

When you set multipassIdentifier to null via the customerUpdate mutation, the API accepts it and your query returns multipassIdentifier: null. But the validation layer for Multipass login isn’t respecting that null, it’s still expecting the previous identifier that was set before you cleared it.

I tested this with a few scenarios:

  1. Set A → Generate token with A = works ✓
  2. Set A → Clear to null → Generate token with B = 422 error ✗ (what you’re hitting)
  3. Set A → Clear to null → Set C → Generate token with C = works ✓
  4. Set A → Clear to null → Set A → Generate token with A = works ✓
  5. Set A → Clear to null → Generate token with A (without re-setting) = 422 error ✗

The pattern here is that clearing to null doesn’t actually “clear” the identifier requirement, it leaves the validation in a state where it seems ANY token with an identifier fails, including the original one (scenario 5). The only way to fix it is to explicitly set a new identifier value (scenarios 3 & 4), which refreshes whatever’s happening in the validation layer.

Workaround for now: Don’t go through null if you’re changing identifiers. Do a direct swap: instead of identifier_old → null → identifier_new, just do identifier_old → identifier_new in one update.

I’m referring this to the product team because null is documented as a valid operation in the API, but it’s not behaving as expected in practice.

Can you confirm the workaround works for your use case? That’ll at least unblock you while I get this looked at internally.

Quick update - I checked with the Multipass team and this is actually expected behavior, just not well documented.

Setting multipassIdentifier to null doesn’t “clear” it like you’d expect, it disables Multipass for that customer entirely. So when the API returns null and you try to generate a token with any identifier (even the original one), Multipass rejects it because it’s treating the customer as “Multipass not allowed.”

The workaround I mentioned (direct identifier swap without going through null) is the right approach. Update the customer record with the new identifier first, then generate your token, that works immediately.

Would be good to see this clarified in the Multipass docs though. I’ll flag that internally.

I understand why you designed it this way. Since you changed the identifier using multipassURL, it is no longer allowed to use different identifiers for login.
But there are two issues in our implementation.

  1. The identifier of the account is null, and we cannot determine whether the user can log in normally through the API because there are two situations: the first is that the user has not set the identifier, and the second is that after setting the identifier, they reset it to null.
    The key issue is that a null value has two meanings at the same time, and we cannot determine which meaning it actually has.
  2. As I mentioned earlier, setting the identifier of an account to A is an incorrect action, and we do not actually want to change it. Its occurrence is due to a bug
    The final identifier for the account, assuming it is B, has not been generated yet.
    In this scenario, there will be two processes:
    a) The identifier has not been set: generate multipassURL>user login>redirect and modify the identifier to B
    b) The identifier has been set: change the identifier to B (via API)>generate multipassURL>user login>redirect and change the identifier to B
    The process we are currently using is a, and we plan to modify it to b, but this process is very unreasonable as users modify their data before logging into Shopify.
    And due to problem 1, coupled with the fact that the error perceived by the user is on Shopify’s side, we are unable to perceive it, so we have to change the process to b. In this way, the multipassURL redirection that changes the identifier to B becomes useless logic.
    Our technical team tends to directly modify the user’s identifier to null, keeping the login process unchanged.

You’re right about the semantic ambiguity. When you see multipassIdentifier: null, you can’t tell if it means “never configured” or “explicitly disabled”. There’s no separate field to distinguish these states, and I’ll flag this with the Multipass team internally.

Your flow (set identifier on first login) works fine for customers who’ve never had an identifier. The problem is customers who previously had the wrong identifier A - once you null it out, they’re in a “disabled” state, not “never configured”.

If you know the correct identifier B in advance, could you skip the null step and just update A → B directly via the API before generating the token? That way the customer’s identifier is already correct when they log in.

If identifier B is generated dynamically at login time, you’d need to update to B via the API first (before generating the token), which means determining B earlier in your flow than you currently do. Not ideal, but it’s the only way to work around the null behavior right now.