paperclipai/paperclip · error · TeamsAdapterCompatibilityError
durable route recorder is unavailable
Error message
durable route recorder is unavailable
What it means
recordMicrosoftTeamsRoute persists the authenticated Bot Connector serviceUrl for a Teams thread using the adapter's internal paperclipRecordThreadServiceUrl hook. For non-Teams providers it is a no-op (early return), but when the provider IS microsoft-teams and the adapter lacks the recorder function, the runtime cannot durably store the route and throws a TeamsAdapterCompatibilityError.
Source
Thrown at server/src/services/chat-sdk-runtime.ts:2546
}
/**
* Persist a Teams activity's authenticated reply route only after the
* control plane has accepted the callback under the current runtime and
* credential generation. The route is intentionally separate from the
* durable provider thread id because Microsoft can move a conversation
* between regional Bot Connector service URLs.
*/
async recordMicrosoftTeamsRoute(
threadId: string,
serviceUrl: unknown,
raw?: unknown,
): Promise<void> {
if (this.provider !== "microsoft-teams") return;
const teams = this.adapter as unknown as TeamsAdapterInternals;
const recorder = teams.paperclipRecordThreadServiceUrl;
if (typeof recorder !== "function") {
throw new TeamsAdapterCompatibilityError(
"durable route recorder is unavailable",
);
}
await recorder.call(this.adapter, threadId, serviceUrl);
if (raw !== undefined) {
const acceptedActivityRecorder = teams.paperclipRecordAcceptedActivity;
if (typeof acceptedActivityRecorder !== "function") {
throw new TeamsAdapterCompatibilityError(
"durable accepted-activity recorder is unavailable",
);
}
await acceptedActivityRecorder.call(this.adapter, raw);
}
}
async sendTeamsFileConsentCard(
threadId: string,
card: ReturnType<typeof buildTeamsFileConsentCard>,View on GitHub (pinned to 01ad858492)
Solutions
- Upgrade the microsoft-teams adapter so it implements paperclipRecordThreadServiceUrl.
- Feature-detect the recorder before calling and skip durable route persistence (log a warning) when absent.
- Align adapter and chat-sdk-runtime versions so the internal contract matches.
Example fix
// before
await runtime.recordMicrosoftTeamsRoute(threadId, serviceUrl, raw);
// after
const teams = runtime.getProviderAdapter() as {
paperclipRecordThreadServiceUrl?: unknown;
};
if (typeof teams.paperclipRecordThreadServiceUrl === "function") {
await runtime.recordMicrosoftTeamsRoute(threadId, serviceUrl, raw);
} else {
console.warn("teams durable route recorder unavailable; skipping persistence");
} Defensive patterns
Strategy: type-guard
Validate before calling
const teams = runtime.getProviderAdapter() as Record<string, unknown>;
if (runtime.provider === "microsoft-teams" && typeof teams.paperclipRecordThreadServiceUrl !== "function") {
console.warn("teams adapter lacks durable route recorder");
} Type guard
function supportsRouteRecording(a: unknown): a is { paperclipRecordThreadServiceUrl: (threadId: string, serviceUrl: unknown) => Promise<void> } {
return typeof a === "object" && a !== null && typeof (a as any).paperclipRecordThreadServiceUrl === "function";
} Try / catch
try {
await runtime.recordMicrosoftTeamsRoute(threadId, serviceUrl, raw);
} catch (err) {
if (err instanceof TeamsAdapterCompatibilityError && err.message.includes("route recorder is unavailable")) {
console.warn("skipping durable route persistence");
} else throw err;
} Prevention
- Keep the microsoft-teams adapter and chat-sdk-runtime versions aligned.
- Feature-detect paperclipRecordThreadServiceUrl at adapter startup and log missing capabilities once.
- Add adapter contract tests covering the paperclip* internal hooks.
When it happens
Trigger: A Teams activity callback invoking recordMicrosoftTeamsRoute(threadId, serviceUrl, raw) where the wired microsoft-teams adapter does not define paperclipRecordThreadServiceUrl — e.g. an older adapter build or a minimal test adapter.
Common situations: Teams adapter version pinned before the durable-routing feature; custom or stub Teams adapters missing paperclip* internals; dependency upgrade that swapped the adapter implementation without updating the runtime expectations.
Related errors
- durable accepted-activity recorder is unavailable
- file publication receipt capture is unavailable
- file publication receipt lookup is unavailable
- file-consent runtime is not enabled
- ensureRootThread is unavailable
AI-assisted analysis of paperclipai/paperclip@01ad858492 (2026-09-10).
Data as JSON: /api/errors/20e0799c4556c6ca.
Report an issue: GitHub.