paperclipai/paperclip · error · SlackAdapterCompatibilityError

file publication receipt capture is unavailable

Error message

file publication receipt capture is unavailable

What it means

After confirming the provider is Slack, the runtime requires the adapter to expose the internal receipt hooks paperclipFileUploadReceiptContext and paperclipResolveFileUploadReceipt. When either is missing, the adapter is too old or too minimal to durably record upload receipts, and a SlackAdapterCompatibilityError is thrown rather than posting without durable receipt capture.

Source

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

   */
  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),
    );
  }

  /** Resolve a previously accepted Slack upload using metadata reads only. */
  async resolveSlackFileUploadReceipt(
    threadId: string,
    fileIds: string[],
  ): Promise<string | null> {
    if (this.provider !== "slack") {
      throw new SlackAdapterCompatibilityError(
        "file publication receipt lookup was called for a non-Slack endpoint",
      );

View on GitHub (pinned to 01ad858492)

Solutions

  1. Upgrade to a Slack adapter version that implements paperclipFileUploadReceiptContext and paperclipResolveFileUploadReceipt.
  2. Feature-detect the internals before calling and fall back to plain Thread.post when absent.
  3. Update test doubles to implement the full SlackAdapterInternals surface.

Example fix

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

// after
const slack = runtime.getProviderAdapter() as {
  paperclipFileUploadReceiptContext?: unknown;
  paperclipResolveFileUploadReceipt?: unknown;
};
if (slack.paperclipFileUploadReceiptContext && typeof slack.paperclipResolveFileUploadReceipt === "function") {
  await runtime.postSlackFilePublication(threadId, message, onUploadAccepted);
} else {
  await runtime.thread(threadId).post(message);
}
Defensive patterns

Strategy: type-guard

Validate before calling

const slack = runtime.getProviderAdapter() as Record<string, unknown>;
const receiptReady = !!slack.paperclipFileUploadReceiptContext && typeof slack.paperclipResolveFileUploadReceipt === "function";
if (!receiptReady) throw new Error("slack adapter lacks file receipt support");

Type guard

function supportsFileReceipts(a: unknown): a is { paperclipFileUploadReceiptContext: object; paperclipResolveFileUploadReceipt: (fileIds: string[], threadId: string) => Promise<string | null> } {
  return typeof a === "object" && a !== null && !!(a as any).paperclipFileUploadReceiptContext && typeof (a as any).paperclipResolveFileUploadReceipt === "function";
}

Try / catch

try {
  await runtime.postSlackFilePublication(threadId, message, onUploadAccepted);
} catch (err) {
  if (err instanceof SlackAdapterCompatibilityError && err.message.includes("receipt capture is unavailable")) {
    await runtime.thread(threadId).post(message);
  } else throw err;
}

Prevention

When it happens

Trigger: Calling postSlackFilePublication against a Slack runtime whose adapter lacks paperclipFileUploadReceiptContext or whose paperclipResolveFileUploadReceipt is not a function — e.g. a stubbed/partial Slack adapter in tests, or a custom Slack adapter that predates the receipt contract.

Common situations: Pinned Chat SDK adapter version older than the file-receipt feature; hand-rolled Slack adapter implementations missing the paperclip* internals; test doubles that mock Thread.post but not the receipt context.

Related errors


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