paperclipai/paperclip · error · TeamsAdapterCompatibilityError
${methodName} is unavailable
Error message
${methodName} is unavailable What it means
scopeMicrosoftTeamsEgress iterates TEAMS_THREAD_SCOPED_METHODS (the adapter's per-thread operations) and asserts each is a function. Thread-scoped methods must all exist because the wrapper re-routes them through withThreadServiceUrl to scope outbound calls to the conversation's verified service URL. A missing method means the wrapper cannot safely proxy the full thread surface, so it throws.
Source
Thrown at server/src/services/chat-sdk-runtime.ts:1032
}
if (typeof teams.decodeThreadId !== "function") {
throw new TeamsAdapterCompatibilityError("decodeThreadId is unavailable");
}
if (typeof teams.openDM !== "function") {
throw new TeamsAdapterCompatibilityError("openDM is unavailable");
}
if (typeof teams.cacheUserContext !== "function") {
throw new TeamsAdapterCompatibilityError("cacheUserContext is unavailable");
}
if (typeof teams.getIncomingUser !== "function") {
throw new TeamsAdapterCompatibilityError("getIncomingUser is unavailable");
}
if (typeof teams.getUser !== "function") {
throw new TeamsAdapterCompatibilityError("getUser is unavailable");
}
for (const methodName of TEAMS_THREAD_SCOPED_METHODS) {
if (typeof teams[methodName] !== "function") {
throw new TeamsAdapterCompatibilityError(`${methodName} is unavailable`);
}
}
if (
typeof teams.app.api.constructor !== "function" ||
!("http" in teams.app.api)
) {
throw new TeamsAdapterCompatibilityError(
"the API client constructor or HTTP transport is unavailable",
);
}
const apiDescriptor = Object.getOwnPropertyDescriptor(teams.app, "api");
if (apiDescriptor && apiDescriptor.configurable === false) {
throw new TeamsAdapterCompatibilityError(
"app.api cannot be scoped per asynchronous conversation",
);
}
const trustedConfiguredApiUrl = configuredApiUrl
? normalizedTeamsServiceUrl(configuredApiUrl)View on GitHub (pinned to 01ad858492)
Solutions
- Read the thrown message to identify which method is missing and check TEAMS_THREAD_SCOPED_METHODS for the full required list.
- Use the official, current Teams adapter implementation rather than a partial reimplementation.
- Update your test mock to implement every thread-scoped method as a function.
- Check the adapter's prototype chain — methods defined only on a class prototype can be lost if the object was spread ({...adapter}).
Example fix
// before (spread drops prototype methods)
const partial = { ...createTeamsAdapter() };
scopeMicrosoftTeamsEgress(partial);
// after
const adapter = createTeamsAdapter(); // keep prototype intact
scopeMicrosoftTeamsEgress(adapter); Defensive patterns
Strategy: validation
Validate before calling
const required = TEAMS_THREAD_SCOPED_METHODS;
const missing = required.filter((m) => typeof (adapter as any)[m] !== 'function');
if (missing.length) throw new Error(`Teams adapter missing thread-scoped methods: ${missing.join(', ')}`); Try / catch
try {
scoped = scopeMicrosoftTeamsEgress(adapter);
} catch (err) {
if (err instanceof TeamsAdapterCompatibilityError && err.message.endsWith('is unavailable')) {
logger.error(`Thread-scoped method missing on Teams adapter: ${err.message}`);
}
throw err;
} Prevention
- Use the official adapter implementation rather than reimplementing subsets of its API.
- Avoid object spreads that drop class-prototype methods ({...adapter}).
- Keep a test that iterates TEAMS_THREAD_SCOPED_METHODS against the adapter instance.
When it happens
Trigger: An adapter object passed to scopeMicrosoftTeamsEgress is missing at least one method listed in TEAMS_THREAD_SCOPED_METHODS; the thrown message names the specific method (e.g. 'postActivity is unavailable').
Common situations: Adapter version mismatch after an upgrade; incomplete test doubles; a custom adapter that implements most but not all thread-scoped methods; tree-shaking or build config dropping prototype methods.
Related errors
- getIncomingUser is unavailable
- getUser is unavailable
- decodeThreadId is unavailable
- openDM is unavailable
- cacheUserContext is unavailable
AI-assisted analysis of paperclipai/paperclip@01ad858492 (2026-09-10).
Data as JSON: /api/errors/a8fd8087d6c34967.
Report an issue: GitHub.