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

  1. 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.
  2. Refresh the chat list so chat guids are current before fetching messages.
  3. 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

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


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.messages

View on GitHub (pinned to 3f1d897a7c)