JMAP Identity object not updated after Account rename (username or domainId change)

Issue Description

When an Account’s name (username/local-part) or domainId is changed via stalwart-cli update Account --field name=… (or via Admin UI equivalent), the computed emailAddress on the Account object updates correctly — but the corresponding JMAP Identity object is not updated and silently keeps the old email address. The Identity object’s state field also does not change, indicating it is not touched at all by the rename operation.

This causes outgoing mail sent via JMAP submission (e.g. from Bulwark webmail) to use the stale, pre-rename address in the From header, with no error surfaced to the user — the message appears to send successfully in the client.

Expected Behavior

Either:

The Identity object’s email should be kept in sync automatically when the underlying Account’s computed emailAddress changes, or
If this is intentional (e.g. treating Identity as an independent, user-managed object per JMAP spec), this should be clearly documented, since the practical effect is that renamed/migrated accounts silently send mail from a stale address with no error surfaced anywhere (not in Bulwark UI, not in server logs at INFO level as far as I could tell).

Actual Behavior

Identity.email and Identity.state remain frozen at their pre-rename values indefinitely, until manually fixed via a Identity/set destroy+create call.

Reproduction Steps

1)Create or use an existing account, e.g. daria@example (short id bg)
2)Confirm an Identity already exists for it:
curl -u “daria@example:PASSWORD” -X POST https://HOST/jmap
-H “Content-Type: application/json”
-d ‘{“using”:[“urn:ietf:params:jmap:core”,“urn:ietf:params:jmap:submission”],“methodCalls”:[[“Identity/get”,{“accountId”:“bg”},“0”]]}’

→ returns email: “daria@example”
3) Rename the account’s username via CLI:

stalwart-cli --url http://localhost:8080 --user admin@… --password … -k
update Account bg --field name=daria-test
4) Confirm the Account itself is correctly renamed:
stalwart-cli … get Account bg

→ Email Address: daria-test@example (correct) 5. Repeat the Identity/get call from step 2 (now authenticating as daria-test@example) → still returns email: “daria@example” (stale), and state is unchanged from step 2

Relevant Log Output

No error appears in logs — the bug is precisely that the stale Identity produces no error anywhere (server logs at default verbosity, Bulwark UI, or client response). Confirmed via direct JMAP calls, not through Bulwark.

Stalwart Version

v0.16.x

Installation Method

Binary (Linux)

Database Backend

RocksDB

Blob Storage

RocksDB

Search Engine

Internal

Directory Backend

Internal

I have reviewed the documentation and FAQ and confirm that my issue is NOT addressed there.

on

I have searched this support forum (open and closed topics) and confirm this is not a duplicate.

on

I understand that topics in this category are triaged by a bot first but a human reply will follow up. If I’d prefer a human-only reply, I’ll add the no-ai tag to my topic.

on

This confirms the reported behavior in the current code. The Identity collection is only touched by identity_set (JMAP Identity/set) and identity_get, there is no code path in the account/principal update logic that touches Collection::Identity when a principal’s name or email changes. So when you rename an account via stalwart-cli update Account ... --field name=..., nothing recomputes or invalidates existing Identity records; they keep whatever email was set when they were created, and their state never bumps because they were never modified.

This isn’t documented as a known limitation, and there’s no automatic sync between the account’s computed email address and Identity.email. Practically, Identity objects are treated as independent, user-managed records (per the JMAP spec model), but nothing currently invalidates or flags stale identities after a rename, and no error is surfaced when JMAP submission uses a stale identity email. This matches what you found: only a manual Identity/set destroy+create (or update) fixes it.

I don’t see anything in the docs describing this as intended behavior, so I can’t confirm from documentation whether this is a deliberate design choice or a gap. Given the reproduction is solid and grounded directly in the identity/set.rs and account-update code paths, this looks like a genuine bug/gap worth a human maintainer’s review rather than something addressed in docs.

This is an automated reply from the Stalwart Help Bot. Other community members may follow up if this answer is incomplete or wrong.

Identities are created once and after that they should be managed by the JMAP client. This is by design, to avoid creating the same identity a user manually removed.
If you are migrating accounts, create a script that deletes all the account’s identities so Stalwart creates them again.