paperclipai/paperclip · error
Photon conversation is unavailable
Error message
Photon conversation is unavailable
What it means
Thrown in PhotonAdapter.publish when the target iMessage chat (resolved via chatInfo) is marked archived. Photon treats archived conversations as unavailable delivery targets, so publication is refused before any send is attempted. It is a pre-flight guard, not a network failure.
Solutions
- Check the chat's archived state before publishing (chatInfo(id).isArchived) and surface a user-visible 'conversation archived' state instead of retrying
- Have the user unarchive the conversation in iMessage, then re-publish with the same publicationId
- Route the publication to a different (active) thread or workspace conversation
- Do not blindly retry: the check is deterministic and will keep failing while the chat stays archived
Example fix
// before await adapter.publish(threadId, pubId, message, opts); // after const chat = await adapter.chatInfo(threadId); if (chat.isArchived) throw new ConversationArchivedError(threadId); await adapter.publish(threadId, pubId, message, opts);
Defensive patterns
Strategy: validation
Validate before calling
const chat = await adapter.chatInfo(threadId);
if (chat.isArchived) throw new Error(`Conversation ${threadId} is archived; cannot publish`); Type guard
function isPublishable(chat) { return !chat.isArchived; } Try / catch
try {
await adapter.publish(id, pubId, msg, opts);
} catch (e) {
if (e.message === 'Photon conversation is unavailable') {
markPublicationBlocked(pubId, 'conversation-archived');
return; // do not retry
}
throw e;
} Prevention
- Check chatInfo().isArchived before starting long agent runs
- Surface archived-thread state in the UI before offering send actions
- Avoid reusing thread ids across long-lived schedules without re-validating the chat
- Treat this as terminal: never auto-retry an archived conversation
When it happens
Trigger: Calling publish(id, publicationId, message, options) where this.client.chats (fetched by chatInfo(id)) reports chat.isArchived === true — i.e. the conversation was archived in iMessage/Photon between publication preparation and this call.
Common situations: A user archived the chat in the Messages app while the agent run was still open; a rerun or replay targets a stale thread id; automated cleanup archived old chats so long-lived publications can no longer deliver.
Understand the failure class
Background: "Invalid state transition" errors: "status must be X, actually Y", "already rejected/charging/uninstalled", "cannot ... while running" — what they mean when a library rejects your call — this error's family across 31 libraries.
Related errors
- Photon cannot edit a multipart publication
- Photon publication is empty
- railway_deployment_ineligible
- There is no current session goal to edit.
AI-assisted analysis of paperclipai/paperclip@3f1d897a7c (2026-09-18).
Data as JSON: /api/errors/1fd48048dcd89941.
Report an issue: GitHub.
Appendix: source
Thrown at server/src/services/photon/adapter.ts:413
/* Receipt reactions are intentionally not published. */
}
async removeReaction(): Promise<void> {
/* Reactions never represent approvals. */
}
async publish(
id: string,
publicationId: string,
message: AdapterPostableMessage,
options: {
replyTo?: string;
replaceMessageId?: string;
retryUnknown?: boolean;
assertCurrent(): Promise<void>;
},
): Promise<{ id: string; messageIds: string[] }> {
const chat = await this.chatInfo(id);
if (chat.isArchived) throw new Error("Photon conversation is unavailable");
const text = textOf(message);
const files =
typeof message !== "string" && "files" in message
? (message.files ?? [])
: [];
const parts = splitPhotonText(text);
if (options.replaceMessageId && (parts.length !== 1 || files.length))
throw new Error("Photon cannot edit a multipart publication");
let lastId: string | undefined;
const messageIds: string[] = [];
for (let index = 0; index < parts.length; index++) {
lastId = await this.sendPart(
publicationId,
`text-${index}`,
{
chatGuid: chat.guid,
text: parts[index],
replyTo: options.replyTo,View on GitHub (pinned to 3f1d897a7c)