paperclipai/paperclip · error · SlackAdapterCompatibilityError

file publication receipt lookup was called for a non-Slack e

Error message

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

What it means

resolveSlackFileUploadReceipt looks up previously accepted Slack upload IDs via the adapter's internal paperclipResolveFileUploadReceipt hook. Because that hook exists only on the Slack adapter, the runtime rejects the call with a SlackAdapterCompatibilityError when the endpoint provider is anything other than 'slack'.

Source

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

      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",
      );
    }
    const slack = this.adapter as unknown as SlackAdapterInternals;
    if (typeof slack.paperclipResolveFileUploadReceipt !== "function") {
      throw new SlackAdapterCompatibilityError(
        "file publication receipt lookup is unavailable",
      );
    }
    return await slack.paperclipResolveFileUploadReceipt.call(
      this.adapter,
      fileIds,
      threadId,
    );
  }

  /**
   * Persist a Teams activity's authenticated reply route only after the

View on GitHub (pinned to 01ad858492)

Solutions

  1. Check the runtime provider is 'slack' before calling resolveSlackFileUploadReceipt; skip or route other providers.
  2. Ensure the receipt lookup runs against the same Slack endpoint runtime that captured the receipt.
  3. For provider-agnostic lookup, branch on provider and use each provider's own reconciliation path.

Example fix

// before
const path = await runtime.resolveSlackFileUploadReceipt(threadId, fileIds);

// after
if (runtime.provider !== "slack") return null;
const path = await runtime.resolveSlackFileUploadReceipt(threadId, fileIds);
Defensive patterns

Strategy: validation

Validate before calling

if (runtime.provider !== "slack") return null; // receipts only exist for Slack endpoints

Type guard

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

Try / catch

try {
  return await runtime.resolveSlackFileUploadReceipt(threadId, fileIds);
} catch (err) {
  if (err instanceof SlackAdapterCompatibilityError) return null; // treat as unresolvable
  throw err;
}

Prevention

When it happens

Trigger: Calling resolveSlackFileUploadReceipt(threadId, fileIds) on a runtime whose provider is not 'slack' — e.g. resolving receipts recorded from a Slack flow but issued against a different endpoint's runtime instance.

Common situations: Receipt lookup code running on the wrong endpoint runtime after a provider reconfiguration; shared reconciliation jobs that iterate all endpoints and call the Slack-only resolver unconditionally; mixed-provider workspaces where a stale thread id belongs to another provider.

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/a1435b5feef490bc. Report an issue: GitHub.