paperclipai/paperclip · error · SlackAdapterCompatibilityError

file publication receipt capture was called for a non-Slack

Error message

file publication receipt capture was called for a non-Slack endpoint

What it means

postSlackFilePublication captures an upload receipt that only the Slack adapter can record, so the runtime first asserts this.provider === 'slack'. Calling it against any other provider's endpoint would leave the receipt callback unresolvable, so a SlackAdapterCompatibilityError is thrown before any message is sent.

Source

Thrown at server/src/services/chat-sdk-runtime.ts:2488

      paperclipDraftControl: control,
    });
  }

  /**
   * Post one Slack file-only publication while durably recording the accepted
   * upload IDs before the adapter performs its eventually-consistent share
   * lookup. This specialized receipt scope is deliberately unavailable for
   * cards, edits, and ordinary text sends; the send still uses Thread.post.
   */
  async postSlackFilePublication(
    threadId: string,
    message: Parameters<Thread["post"]>[0],
    onUploadAccepted: (
      receipt: SlackFileUploadAcceptedReceipt,
    ) => Promise<void>,
  ): Promise<{ id: string }> {
    if (this.provider !== "slack") {
      throw new SlackAdapterCompatibilityError(
        "file publication receipt capture was called for a non-Slack endpoint",
      );
    }
    const slack = this.adapter as unknown as SlackAdapterInternals;
    if (
      !slack.paperclipFileUploadReceiptContext ||
      typeof slack.paperclipResolveFileUploadReceipt !== "function"
    ) {
      throw new SlackAdapterCompatibilityError(
        "file publication receipt capture is unavailable",
      );
    }
    return await slack.paperclipFileUploadReceiptContext.run(
      onUploadAccepted,
      async () => await this.chat.thread(threadId).post(message),
    );
  }

View on GitHub (pinned to 01ad858492)

Solutions

  1. Guard the call with a provider check (runtime provider === 'slack') and route other providers to their normal Thread.post path.
  2. Fix endpoint/provider configuration so the file publication flow runs against a Slack endpoint.
  3. If generic file publishing is needed for all providers, use the provider-agnostic Thread.post API instead of the Slack-specific receipt path.

Example fix

// before
await runtime.postSlackFilePublication(threadId, message, onUploadAccepted);

// after
if (runtime.provider === "slack") {
  await runtime.postSlackFilePublication(threadId, message, onUploadAccepted);
} else {
  await runtime.thread(threadId).post(message);
}
Defensive patterns

Strategy: validation

Validate before calling

if (runtime.provider !== "slack") throw new Error("postSlackFilePublication requires a Slack endpoint");

Type guard

function isSlackRuntime(r: { provider: string }): boolean { return r.provider === "slack"; }

Try / catch

try {
  await runtime.postSlackFilePublication(threadId, message, onUploadAccepted);
} catch (err) {
  if (err instanceof SlackAdapterCompatibilityError) {
    await runtime.thread(threadId).post(message);
  } else throw err;
}

Prevention

When it happens

Trigger: Invoking postSlackFilePublication(threadId, message, onUploadAccepted) on a runtime whose endpoint provider is not 'slack' (e.g. telegram, discord, microsoft-teams).

Common situations: Shared send-helper code reused across provider endpoints without checking the provider; misconfigured endpoint mapping that routes a Slack-specific file flow to a Teams or Telegram runtime; tests instantiating a non-Slack adapter but exercising Slack publication code.

Understand the failure class

Background: UnsupportedOperationException and "is not supported" errors: when a library deliberately refuses a call — this error's family across 30 libraries.

Related errors


AI-assisted analysis of paperclipai/paperclip@01ad858492 (2026-09-10). Data as JSON: /api/errors/18c9b09fafb5b194. Report an issue: GitHub.