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

  1. Check that the adapter passed to scopeMicrosoftTeamsEgress is the real Microsoft Teams adapter and that it defines getIncomingUser (typeof adapter.getIncomingUser === 'function').
  2. Upgrade or pin the Teams adapter package to the version Paperclip expects so the internal method exists.
  3. If using a test double, add getIncomingUser (it may be async () => null since the wrapper replaces it anyway).
  4. 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

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


AI-assisted analysis of paperclipai/paperclip@01ad858492 (2026-09-10). Data as JSON: /api/errors/823f8651bea2d236. Report an issue: GitHub.