paperclipai/paperclip · error · TeamsAdapterCompatibilityError
getIncomingUser is unavailable
Error message
getIncomingUser is unavailable
What it means
scopeMicrosoftTeamsEgress performs a structural compatibility audit of the Microsoft Teams adapter before wrapping it. getIncomingUser is one of the required adapter methods Paperclip stubs out to keep unadmitted events observationally inert; if the adapter object lacks it, the runtime refuses to proceed rather than silently misrouting Teams traffic. This guards against running against an adapter version or shape that no longer matches the pinned contract.
Source
Thrown at server/src/services/chat-sdk-runtime.ts:1025
adapter: Adapter,
configuredApiUrl?: string,
enableFileConsent = false,
): Adapter {
const teams = adapter as unknown as TeamsAdapterInternals;
if (!teams.app?.api) {
throw new TeamsAdapterCompatibilityError("app.api is unavailable");
}
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");View on GitHub (pinned to 01ad858492)
Solutions
- Check that the adapter passed to scopeMicrosoftTeamsEgress is the real Microsoft Teams adapter and that it defines getIncomingUser (typeof adapter.getIncomingUser === 'function').
- Upgrade or pin the Teams adapter package to the version Paperclip expects so the internal method exists.
- If using a test double, add getIncomingUser (it may be async () => null since the wrapper replaces it anyway).
- Verify the adapter object is not being constructed from a partial type cast that drops methods.
Example fix
// before
scopeMicrosoftTeamsEgress({ app, decodeThreadId, openDM } as unknown as Adapter);
// after
const teamsAdapter = createTeamsAdapter(); // full adapter including getIncomingUser
scopeMicrosoftTeamsEgress(teamsAdapter); Defensive patterns
Strategy: validation
Validate before calling
if (typeof adapter.getIncomingUser !== 'function') {
throw new Error('Teams adapter missing getIncomingUser; incompatible adapter version');
} Type guard
function hasGetIncomingUser(a: unknown): a is { getIncomingUser: (...args: unknown[]) => unknown } {
return typeof a === 'object' && a !== null && typeof (a as any).getIncomingUser === 'function';
} Try / catch
try {
scoped = scopeMicrosoftTeamsEgress(adapter);
} catch (err) {
if (err instanceof TeamsAdapterCompatibilityError && /getIncomingUser/.test(err.message)) {
logger.error('Teams adapter is missing getIncomingUser — upgrade or replace the adapter package');
}
throw err;
} Prevention
- Pin the Teams adapter package version Paperclip expects and review breaking changes on upgrade.
- Before calling scopeMicrosoftTeamsEgress, assert the full required method surface (app.api, decodeThreadId, openDM, cacheUserContext, getIncomingUser, getUser).
- Never spread-copy adapter instances; keep the prototype chain intact.
- In CI, add a smoke test that wraps the real adapter with scopeMicrosoftTeamsEgress.
When it happens
Trigger: Calling scopeMicrosoftTeamsEgress with an adapter whose TeamsAdapterInternals does not expose getIncomingUser as a function — e.g. a custom adapter, a mocked adapter missing the method, or a Teams adapter package version that renamed/removed it.
Common situations: Upgrading or swapping the Teams adapter package so internal methods changed; passing the wrong adapter (non-Teams) into scopeMicrosoftTeamsEgress; a hand-rolled test double that only implements part of the adapter surface.
Related errors
- getUser is unavailable
- ${methodName} 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/823f8651bea2d236.
Report an issue: GitHub.