paperclipai/paperclip · error · TeamsAdapterCompatibilityError
cacheUserContext is unavailable
Error message
cacheUserContext is unavailable
What it means
Continuing the same compatibility gate, the runtime requires adapter.cacheUserContext to be a function; when absent it throws TeamsAdapterCompatibilityError('cacheUserContext is unavailable'). Without it the runtime cannot persist Teams user context across turns and refuses to wire the adapter.
Source
Thrown at server/src/services/chat-sdk-runtime.ts:1022
* forcing unrelated Teams threads through a single network queue.
*/
export function scopeMicrosoftTeamsEgress(
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",View on GitHub (pinned to 01ad858492)
Solutions
- Bring the Teams adapter package to the version the runtime expects (all required internals present).
- Implement cacheUserContext on the custom adapter with the expected signature.
- Add cacheUserContext: vi.fn() to test doubles.
- After fixing, re-run so the gate proceeds to the remaining checks (getIncomingUser, getUser).
Example fix
// before
const adapter = { app: { api: {} }, decodeThreadId: vi.fn(), openDM: vi.fn() };
// after
const adapter = { app: { api: {} }, decodeThreadId: vi.fn(), openDM: vi.fn(), cacheUserContext: vi.fn() }; Defensive patterns
Strategy: type-guard
Validate before calling
const teams = adapter as unknown as TeamsAdapterInternals;
if (typeof teams.cacheUserContext !== "function") throw new Error("adapter missing cacheUserContext"); Type guard
function supportsCacheUserContext(a: unknown): a is TeamsAdapterInternals {
return typeof (a as TeamsAdapterInternals)?.cacheUserContext === "function";
} Try / catch
try {
wireTeamsAdapter(adapter);
} catch (e) {
if (e instanceof TeamsAdapterCompatibilityError && e.message.includes("cacheUserContext")) {
// implement/upgrade so cacheUserContext exists
}
} Prevention
- Run the full compatibility gate in a smoke test at CI time for every adapter version bump.
- Implement the entire internal contract (app.api, decodeThreadId, openDM, cacheUserContext, getIncomingUser, getUser) in custom adapters.
- Complete stubs iteratively: after fixing one missing method, re-run to catch the next.
- Keep adapter and runtime packages upgraded together in the same change.
When it happens
Trigger: Providing a Teams adapter whose internals have app.api, decodeThreadId, and openDM but lack a cacheUserContext function — typically a version mismatch or an incomplete stub, since the checks run sequentially and this one fails only after the earlier methods passed.
Common situations: Partially upgraded adapter package where some methods were added in one release and others in a later one; custom adapter covering the thread/DM APIs but not user-context caching; mocks extended only as far as the previous failure.
Related errors
- decodeThreadId is unavailable
- openDM is unavailable
- getIncomingUser is unavailable
- getUser is unavailable
- ${methodName} is unavailable
AI-assisted analysis of paperclipai/paperclip@01ad858492 (2026-09-10).
Data as JSON: /api/errors/91f955afdb7ecae5.
Report an issue: GitHub.