{"record":{"id":"50fdbe6aed796b8e","repo":"CherryHQ/cherry-studio","slug":"channel-type-this-channeltype-does-not-suppor","errorCode":null,"errorMessage":"Channel type \"${this.channelType}\" does not support sending files","messagePattern":"Channel type \"(.+?)\" does not support sending files","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"warning","filePath":"src/main/ai/channels/ChannelAdapter.ts","lineNumber":216,"sourceCode":"   */\n  protected abstract performConnect(signal: AbortSignal): Promise<void>\n\n  /**\n   * Tear down the connection. Release resources, stop polling, close sockets.\n   */\n  protected abstract performDisconnect(): Promise<void>\n\n  abstract sendMessage(chatId: string, text: string, opts?: SendMessageOptions): Promise<void>\n  abstract sendTypingIndicator(chatId: string): Promise<void>\n\n  /**\n   * Send a file to a chat. Non-abstract so adapters can adopt outbound file\n   * forwarding incrementally — the default rejects with a clear reason for\n   * adapters whose platform upload isn't wired yet.\n   */\n  // oxlint-disable-next-line no-unused-vars\n  async sendFile(_chatId: string, _file: FileAttachment): Promise<void> {\n    throw new Error(`Channel type \"${this.channelType}\" does not support sending files`)\n  }\n\n  /**\n   * Called on every text update during streaming. The adapter decides\n   * internally when/how to flush to the platform (throttle, mutex, etc.).\n   * @param fullText - The full cumulative response text so far.\n   */\n  // oxlint-disable-next-line no-unused-vars\n  async onTextUpdate(_chatId: string, _fullText: string): Promise<void> {\n    // Default no-op — adapters that support streaming should override.\n  }\n\n  /**\n   * Called when the stream is complete. The adapter should finalize the\n   * streaming UI (close streaming card, send final message, etc.).\n   * @returns true if the adapter handled the final delivery (e.g. updated the card).\n   *          false means the caller should fall back to sendMessage().\n   */","sourceCodeStart":198,"sourceCodeEnd":234,"githubUrl":"https://github.com/CherryHQ/cherry-studio/blob/726446b54cd69ffe51a276638672f6d95ca0768c/src/main/ai/channels/ChannelAdapter.ts#L198-L234","documentation":"Thrown by the default ChannelAdapter.sendFile — a non-abstract method so adapters can adopt outbound file forwarding incrementally. Any adapter that has not overridden sendFile hits this default, which rejects with the adapter's channelType in the message. It signals an unsupported capability, not a runtime fault: file forwarding was requested on a channel whose platform upload path is not wired.","triggerScenarios":"Message-handling code calls adapter.sendFile(chatId, file) on a ChannelAdapter subclass that did not override sendFile (e.g. a channel with no platform file-upload implementation).","commonSituations":"A user forwards/attaches a file in a channel whose adapter only implements text; a new channel adapter was added without file support; file-forwarding feature enabled globally but not all adapters support it.","solutions":["Before calling sendFile, check whether the adapter supports it (capability flag / `sendFile === ChannelAdapter.prototype.sendFile`), and skip or fall back to a text link for unsupported channels.","If the channel should support files, implement sendFile in that adapter (upload to the platform, then send).","Gate the file-forwarding UI/feature per channel type so users cannot trigger it on unsupported adapters.","Catch the error at the call site and degrade gracefully (e.g. send a text notice) instead of failing the whole message."],"exampleFix":"// before: unconditionally send files\nawait adapter.sendFile(chatId, file)\n\n// after: capability check + graceful fallback\nif (adapter.supportsFiles) {\n  await adapter.sendFile(chatId, file)\n} else {\n  await adapter.sendMessage(chatId, `[file: ${file.name}]`)\n}","handlingStrategy":"type-guard","validationCode":"function adapterSupportsFiles(adapter: ChannelAdapter): boolean {\n  return adapter.sendFile !== ChannelAdapter.prototype.sendFile\n}\nif (adapterSupportsFiles(adapter)) {\n  await adapter.sendFile(chatId, file)\n} else {\n  await adapter.sendMessage(chatId, `[file: ${file.name}]`)\n}","typeGuard":"function supportsFileSend(adapter: ChannelAdapter): boolean {\n  return adapter.sendFile !== ChannelAdapter.prototype.sendFile\n}","tryCatchPattern":"try {\n  await adapter.sendFile(chatId, file)\n} catch (e) {\n  if (e instanceof Error && /does not support sending files/.test(e.message)) {\n    await adapter.sendMessage(chatId, `[file: ${file.name}]`) // graceful fallback\n  } else throw e\n}","preventionTips":["Gate file-forwarding per channel capability, not globally.","Implement sendFile when adding a new channel adapter that should forward files.","Degrade to a text notice instead of failing the whole message."],"tags":["channels","adapters","capabilities","files","not-implemented"],"backgroundTag":null,"analyzedSha":"726446b54cd69ffe51a276638672f6d95ca0768c","analyzedAt":"2026-08-12T17:30:37.448Z","schemaVersion":2},"datasetVersion":"2026-08-12T18:17:37.767Z"}