{"record":{"id":"4ff8f6da293f0db3","repo":"paperclipai/paperclip","slug":"rejected","errorCode":"rejected","errorMessage":"Photon shared channels support direct messages only","messagePattern":"Photon shared channels support direct messages only","errorType":"exception","errorClass":"PhotonError","httpStatus":null,"severity":"error","filePath":"server/src/services/photon/adapter.ts","lineNumber":147,"sourceCode":"        channelOptions: {\n          \"grpc.max_receive_message_length\": MAX_ATTACHMENT_BYTES + 1024 * 1024,\n        },\n      });\n  }\n  async initialize(_chat: ChatInstance): Promise<void> {\n    await this.authentication.token();\n  }\n  async disconnect(): Promise<void> {\n    this.closed = true;\n    for (const timer of this.typing.values()) clearTimeout(timer);\n    this.typing.clear();\n    this.authentication.retire();\n    this.recovery?.close();\n    await this.client.close();\n  }\n  encodeThreadId(value: PhotonThread): string {\n    if (value.isGroup && this.authentication.identity.allocation === \"shared\")\n      throw new PhotonError(\"rejected\", \"Photon shared channels support direct messages only\");\n    if (value.lineId !== this.authentication.identity.lineId)\n      throw new Error(\"Wrong Photon line\");\n    return photonThreadId(value);\n  }\n  decodeThreadId(id: string): PhotonThread {\n    const value = parsePhotonThreadId(id);\n    if (value.isGroup && this.authentication.identity.allocation === \"shared\")\n      throw new PhotonError(\"rejected\", \"Photon shared channels support direct messages only\");\n    if (value.lineId !== this.authentication.identity.lineId)\n      throw new Error(\"Wrong Photon line\");\n    return value;\n  }\n  channelIdFromThreadId(id: string): string {\n    this.decodeThreadId(id);\n    return id;\n  }\n  isDM(id: string): boolean {\n    return !this.decodeThreadId(id).isGroup;","sourceCodeStart":129,"sourceCodeEnd":165,"githubUrl":"https://github.com/paperclipai/paperclip/blob/3f1d897a7c018d76563a21c6e39c3c9b03933622/server/src/services/photon/adapter.ts#L129-L165","documentation":"encodeThreadId converts a PhotonThread into its string thread id. If the thread is a group chat but the authenticated identity uses a 'shared' allocation, it throws PhotonError('rejected', ...) because shared Photon channels only support direct-message threads. It also throws 'Wrong Photon line' if the thread belongs to a different line.","triggerScenarios":"Encoding a group PhotonThread while the adapter's authentication identity has allocation === 'shared'; e.g. sending/posting to a group channel over a shared-channel identity.","commonSituations":"An identity allocated as 'shared' (shared Photon channel) being reused for group messaging; a config or allocation change switched the identity from dedicated to shared while existing group threads are still addressed.","solutions":["Use a direct-message thread (isGroup === false) with the shared allocation identity.","Re-allocate the identity as a dedicated (non-shared) allocation if group messaging is required.","Update routing so group threads map to a dedicated-line identity before calling encodeThreadId."],"exampleFix":"// before\nconst threadId = adapter.encodeThreadId(groupThread);\n// after\nif (groupThread.isGroup && identity.allocation === \"shared\") {\n  throw new UnsupportedGroupError(); // route group sends through a dedicated identity\n}\nconst threadId = adapter.encodeThreadId(groupThread);","handlingStrategy":"validation","validationCode":"if (thread.isGroup && identity.allocation === \"shared\") throw new Error(\"group threads require a dedicated Photon allocation\");","typeGuard":"const canEncode = (t) => !(t.isGroup && authentication.identity.allocation === \"shared\");","tryCatchPattern":"let id;\ntry {\n  id = adapter.encodeThreadId(thread);\n} catch (e) {\n  if (e.message.includes(\"shared channels\")) { routeToDedicatedIdentity(thread); return; }\n  throw e;\n}","preventionTips":["Track the identity allocation ('shared' vs dedicated) and gate group operations on it.","Keep a mapping of group threads to dedicated identities.","Re-audit thread routing after any allocation change."],"tags":["photon","messaging","unsupported-operation"],"backgroundTag":"unsupported-operation","analyzedSha":"3f1d897a7c018d76563a21c6e39c3c9b03933622","analyzedAt":"2026-09-18T08:03:59.046Z","contentChangedAt":"2026-09-18T08:03:59.046Z","schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}