fix: skip LID chats that fail IndexedDB group metadata lookup

- Replace Promise.all in getChats() with sequential try/catch so one
  bad chat does not discard every chat
- Wrap groupMetadata.update(chatWid) in try/catch — LID-based chat IDs
  (@lid) fail IndexedDB lookup, causing DataError
- Add getMsgKeyId() helper that falls back _serialized -> $1 to tolerate
  WhatsApp Web's recent rename of the serialized property
- Use getMsgKeyId() in sendMessage, editMessage, getMessageModel and
  getChatModel instead of raw ._serialized access
- Restore _serialized on msg.id in getMessageModel so downstream
  consumers of message.id._serialized keep working
This commit is contained in:
Carlos Alaniz 2026-07-16 16:57:45 -05:00 • committed by Eddy de Vink
commit c3a6092bea

View file

@ -582,7 +582,7 @@ exports.LoadUtils = () => {
return window
.require('WAWebCollections')
.Msg.get(newMsgKey._serialized);
.Msg.get(window.WWebJS.getMsgKeyId(newMsgKey));
};
window.WWebJS.editMessage = async (msg, content, options = {}) => {
@ -625,7 +625,9 @@ exports.LoadUtils = () => {
await window
.require('WAWebSendMessageEditAction')
.sendMessageEdit(msg, content, internalOptions);
return window.require('WAWebCollections').Msg.get(msg.id._serialized);
return window
.require('WAWebCollections')
.Msg.get(window.WWebJS.getMsgKeyId(msg.id));
};
window.WWebJS.toStickerData = async (mediaInfo) => {
@ -834,6 +836,20 @@ exports.LoadUtils = () => {
});
}
// The rename reaches the serialized model too: `msg.id` comes back carrying `$1` and no
// `_serialized`, so every consumer of `message.id._serialized` — including this library's own
// Message structure and anything keyed on a message id — silently receives undefined. Restore
// it here, where `msg.id.remote` is already normalised, so the whole downstream surface keeps
// working rather than each caller having to know about `$1`.
if (typeof msg.id === 'object' && msg.id._serialized == null) {
const serializedId = window.WWebJS.getMsgKeyId(msg.id);
if (serializedId) {
msg.id = Object.assign({}, msg.id, {
_serialized: serializedId,
});
}
}
delete msg.pendingAckUpdate;
return msg;
@ -917,12 +933,34 @@ exports.LoadUtils = () => {
};
};
/**
* The serialized id of a message key, tolerating WhatsApp Web having renamed the key's
* `_serialized` property to `$1`. Reading the old name now returns `undefined`, which reaches
* IndexedDB as a `.get(undefined)` and throws
* `DataError: Failed to execute 'get' on 'IDBObjectStore': No key or key range specified.`
* `_serialized` is preferred so nothing changes wherever it is still present (chat ids, for
* example, are unaffected by the rename). Returns undefined when neither exists, so callers can
* skip the lookup instead of querying a store with a nullish key.
* @param {Object} key a message key, e.g. `chat.lastReceivedKey` or a raw `msg.id`
* @returns {string|undefined}
*/
window.WWebJS.getMsgKeyId = (key) =>
key?._serialized ?? key?.$1 ?? undefined;
window.WWebJS.getChats = async () => {
const chats = window.require('WAWebCollections').Chat.getModelsArray();
const chatPromises = chats.map((chat) =>
window.WWebJS.getChatModel(chat),
);
return await Promise.all(chatPromises);
// Process each chat individually — one failure should not discard every chat
const results = [];
for (const chat of chats) {
try {
const model = await window.WWebJS.getChatModel(chat);
if (model) results.push(model);
} catch {
// skip chats that fail serialization (e.g. LID-based group metadata issues)
}
}
return results;
};
window.WWebJS.getChannels = async () => {
@ -957,7 +995,12 @@ exports.LoadUtils = () => {
const groupMetadata =
window.require('WAWebCollections').GroupMetadata ||
window.require('WAWebCollections').WAWebGroupMetadataCollection;
await groupMetadata.update(chatWid);
try {
await groupMetadata.update(chatWid);
} catch {
// LID-based chat IDs may not be found in IndexedDB — skip group metadata
model.groupMetadata = null;
}
const { toPn } = window.require('WAWebLidMigrationUtils');
const serializedMetadata = chat.groupMetadata.serialize();
for (const p of serializedMetadata.participants || []) {
@ -981,16 +1024,17 @@ exports.LoadUtils = () => {
model.lastMessage = null;
if (model.msgs && model.msgs.length) {
const lastMessage = chat.lastReceivedKey
const lastReceivedKeyId = window.WWebJS.getMsgKeyId(
chat.lastReceivedKey,
);
const lastMessage = lastReceivedKeyId
? window
.require('WAWebCollections')
.Msg.get(chat.lastReceivedKey._serialized) ||
.Msg.get(lastReceivedKeyId) ||
(
await window
.require('WAWebCollections')
.Msg.getMessagesById([
chat.lastReceivedKey._serialized,
])
.Msg.getMessagesById([lastReceivedKeyId])
)?.messages?.[0]
: null;
lastMessage &&