paperclipai/paperclip · error
Photon message belongs to another chat
Error message
Photon message belongs to another chat
What it means
normalize converts a raw Photon message into a Paperclip Message, scoped to a given PhotonChat. Every raw Photon message carries a chatGuids array; if the target chat's guid is not among them, the message belongs to a different chat and normalize throws 'Photon message belongs to another chat'. This is an internal consistency check used by fetchMessage and fetchMessages.
Solutions
- Ensure the PhotonChat passed to normalize is the same chat the messages were fetched for; fetch messages per chat rather than from a shared cache.
- Refresh the chat list so chat guids are current before fetching messages.
- Check raw.chatGuids.includes(chat.guid) before calling normalize and route the message to the matching chat instead.
Example fix
// before const normalized = adapter.normalize(rawMessage, cachedChat); // after const chat = rawMessage.chatGuids.includes(cachedChat.guid) ? cachedChat : await getChatByGuid(rawMessage.chatGuids[0]); const normalized = adapter.normalize(rawMessage, chat);
Defensive patterns
Strategy: type-guard
Validate before calling
if (!raw.chatGuids.includes(chat.guid)) { /* mismatch: resolve correct chat first */ } Type guard
const belongsToChat = (raw: PhotonMessage, chat: PhotonChat) => raw.chatGuids.includes(chat.guid);
Try / catch
try {
return adapter.normalize(raw, chat);
} catch (e) {
if (e.message === "Photon message belongs to another chat") return resolveAndNormalize(raw);
throw e;
} Prevention
- Fetch messages per chat and normalize immediately; avoid cross-chat message caches.
- Refresh chat guids after any Photon chat migration.
- Key message caches by (chatGuid, messageId), not messageId alone.
When it happens
Trigger: fetchMessage/fetchMessages invoked with a chat whose guid is absent from raw.chatGuids — e.g. a cached chat object paired with messages fetched for a different chat, or a stale chat guid after a chat was migrated.
Common situations: Concurrent chat updates causing a chat record to be mismatched with its message batch; caching PhotonMessages by message id and re-normalizing them against a different PhotonChat; a chat guid changing server-side while the local cache still holds the old one.
Understand the failure class
Background: "Must be a positive integer", "Invalid value", "Unsupported": the invalid-argument-value error family, when a library rejects the value you pass — this error's family across 35 libraries.
Related errors
- Photon edits require an immutable Paperclip publication…
- Photon message deletion is not supported
- Photon sends require an immutable Paperclip publication…
- rejected
- delivery_unknown
AI-assisted analysis of paperclipai/paperclip@3f1d897a7c (2026-09-18).
Data as JSON: /api/errors/3b12fab2e05bcd92.
Report an issue: GitHub.
Appendix: source
Thrown at server/src/services/photon/adapter.ts:294
fullName: address,
isBot: false,
isMe: raw.isFromMe,
isSystem:
raw.isSystemMessage ||
raw.isServiceMessage ||
!address ||
(service !== "iMessage" && !raw.isFromMe),
},
metadata: {
dateSent: new Date(raw.dateCreated),
edited: !!raw.dateEdited,
editedAt: raw.dateEdited ? new Date(raw.dateEdited) : undefined,
},
});
}
normalize(raw: PhotonMessage, chat: PhotonChat): Message<PhotonMessage> {
if (!raw.chatGuids.includes(chat.guid))
throw new Error("Photon message belongs to another chat");
return this.parseMessage({
...raw,
chatGuids: [chat.guid],
paperclipIsGroup: chat.isGroup,
} as PhotonMessage);
}
async fetchMessage(id: string, messageId: string) {
const chat = await this.chatInfo(id);
return this.normalize(
await this.client.messages.get(messageId).catch((error) => {
throw photonFailure(error);
}),
chat,
);
}
async fetchMessages(id: string, options?: FetchOptions) {
const chat = await this.chatInfo(id);
const page = await this.client.messagesView on GitHub (pinned to 3f1d897a7c)