{"record":{"id":"466d443c4cdeca18","repo":"paperclipai/paperclip","slug":"file-consent-runtime-is-not-enabled","errorCode":null,"errorMessage":"file-consent runtime is not enabled","messagePattern":"file-consent runtime is not enabled","errorType":"exception","errorClass":"TeamsAdapterCompatibilityError","httpStatus":null,"severity":"error","filePath":"server/src/services/chat-sdk-runtime.ts","lineNumber":2586,"sourceCode":"\n  async sendTeamsUploadedFileCard(\n    threadId: string,\n    card: ReturnType<typeof buildTeamsUploadedFileCard>,\n  ): Promise<{ id: string }> {\n    return await this.sendTeamsFileCard(threadId, \"file_info\", card);\n  }\n\n  private async sendTeamsFileCard(\n    threadId: string,\n    kind: \"consent\" | \"file_info\",\n    card: unknown,\n  ): Promise<{ id: string }> {\n    const teams = this.adapter as unknown as TeamsAdapterInternals;\n    if (\n      !this.teamsFileConsentEnabled ||\n      typeof teams.paperclipSendFileCard !== \"function\"\n    ) {\n      throw new TeamsAdapterCompatibilityError(\n        \"file-consent runtime is not enabled\",\n      );\n    }\n    return await teams.paperclipSendFileCard(threadId, kind, card);\n  }\n\n  channel(channelId: string): Channel {\n    return this.chat.channel(channelId);\n  }\n\n  async openDirectMessage(user: string | Author): Promise<Thread> {\n    return await this.chat.openDM(user);\n  }\n\n  async getUser(user: string | Author): Promise<UserInfo | null> {\n    return await this.chat.getUser(user);\n  }\n","sourceCodeStart":2568,"sourceCodeEnd":2604,"githubUrl":"https://github.com/paperclipai/paperclip/blob/01ad8584922b5d85292b1723cae71fa0d9b07a19/server/src/services/chat-sdk-runtime.ts#L2568-L2604","documentation":"sendTeamsFileCard (used by sendTeamsFileConsentCard and sendTeamsUploadedFileCard) requires two things: the runtime was created with the Teams file-consent feature enabled (this.teamsFileConsentEnabled) and the adapter exposes paperclipSendFileCard. If either is missing, the file-consent runtime is considered off and a TeamsAdapterCompatibilityError is thrown instead of attempting to send a consent/file card.","triggerScenarios":"Calling sendTeamsFileConsentCard or sendTeamsUploadedFileCard when: (1) the endpoint runtime was built without the file-consent option (teamsFileConsentEnabled false), or (2) the microsoft-teams adapter lacks paperclipSendFileCard.","commonSituations":"Deployments where the Teams file-consent runtime flag was never enabled in endpoint configuration but upload code paths call it; older Teams adapters predating the file-card hook; tests constructing the runtime without the consent option.","solutions":["Enable the Teams file-consent runtime option when constructing/annotating the endpoint runtime.","Upgrade the microsoft-teams adapter to one implementing paperclipSendFileCard.","Feature-detect (adapter hook present AND consent enabled) before calling, and fall back to a plain text message linking the file.","Verify configuration/env that feeds teamsFileConsentEnabled at startup."],"exampleFix":"// before\nawait runtime.sendTeamsFileConsentCard(threadId, card);\n\n// after\nconst teams = runtime.getProviderAdapter() as {\n  paperclipSendFileCard?: unknown;\n};\nif (runtime.teamsFileConsentEnabled && typeof teams.paperclipSendFileCard === \"function\") {\n  await runtime.sendTeamsFileConsentCard(threadId, card);\n} else {\n  await runtime.thread(threadId).post(fileLinkText);\n}","handlingStrategy":"validation","validationCode":"const teams = runtime.getProviderAdapter() as Record<string, unknown>;\nconst canSendFileCard = (runtime as { teamsFileConsentEnabled?: boolean }).teamsFileConsentEnabled === true && typeof teams.paperclipSendFileCard === \"function\";\nif (!canSendFileCard) throw new Error(\"teams file-consent not available; use plain message\");","typeGuard":"function supportsTeamsFileCards(r: unknown): boolean {\n  const rt = r as { teamsFileConsentEnabled?: boolean; getProviderAdapter?: () => unknown };\n  const a = rt.getProviderAdapter?.() as { paperclipSendFileCard?: unknown } | undefined;\n  return rt.teamsFileConsentEnabled === true && typeof a?.paperclipSendFileCard === \"function\";\n}","tryCatchPattern":"try {\n  await runtime.sendTeamsFileConsentCard(threadId, card);\n} catch (err) {\n  if (err instanceof TeamsAdapterCompatibilityError && err.message.includes(\"file-consent runtime is not enabled\")) {\n    await runtime.thread(threadId).post(fileLinkText);\n  } else throw err;\n}","preventionTips":["Enable the file-consent runtime option in endpoint configuration wherever Teams file uploads are used.","Check teamsFileConsentEnabled at startup and surface a misconfiguration early.","Feature-detect paperclipSendFileCard before constructing consent cards."],"tags":["microsoft-teams","adapter-compatibility","file-consent","feature-flag"],"backgroundTag":"feature-not-enabled","analyzedSha":"01ad8584922b5d85292b1723cae71fa0d9b07a19","analyzedAt":"2026-09-10T03:14:50.855Z","contentChangedAt":"2026-09-10T03:14:50.855Z","schemaVersion":2},"datasetVersion":"2026-09-14T05:17:10.506Z"}