{"record":{"id":"e0570266bff1dd9b","repo":"paperclipai/paperclip","slug":"github-receipt-runtime-unavailable","errorCode":null,"errorMessage":"GitHub receipt runtime unavailable","messagePattern":"GitHub receipt runtime unavailable","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"server/src/services/chat-sdk-runtime.ts","lineNumber":2773,"sourceCode":"      endpointId: this.endpointId,\n      tenantId: this.microsoftTeamsTenantId,\n      botAppId: this.microsoftTeamsAppId,\n      runtimeGeneration: source.runtimeGeneration,\n      credentialFingerprint: source.credentialFingerprint,\n      threadId: source.threadId,\n      messageId: source.messageId,\n      principalExternalId: source.principalExternalId,\n    };\n  }\n\n  /** Service-owned receipt action; no ordinary message or native status retry. */\n  async applyGitHubReceiptReaction(\n    input: GitHubReceiptMutation,\n    assertCurrent: () => Promise<void>,\n    fetchImpl?: typeof globalThis.fetch,\n  ) {\n    if (this.provider !== \"github\" || !this.githubReceiptApp)\n      throw new Error(\"GitHub receipt runtime unavailable\");\n    return applyGitHubReceiptReaction(\n      this.adapter,\n      this.githubReceiptApp.appId,\n      this.githubReceiptApp.installationId,\n      input,\n      assertCurrent,\n      fetchImpl,\n    );\n  }\n\n  async applySlackReceiptReaction(\n    input: SlackReceiptMutation,\n    fetchImpl?: typeof globalThis.fetch,\n  ): Promise<void> {\n    if (this.provider !== \"slack\" || !this.slackReceiptBotToken)\n      throw new Error(\"Slack receipt runtime unavailable\");\n    await applySlackReceiptReaction(\n      { ...input, botToken: this.slackReceiptBotToken },","sourceCodeStart":2755,"sourceCodeEnd":2791,"githubUrl":"https://github.com/paperclipai/paperclip/blob/01ad8584922b5d85292b1723cae71fa0d9b07a19/server/src/services/chat-sdk-runtime.ts#L2755-L2791","documentation":"applyGitHubReceiptReaction is a runtime-level wrapper that re-adds a GitHub receipt reaction using the GitHub App credential captured at runtime construction. The wrapper refuses to run unless the active chat provider is 'github' AND a githubReceiptApp (appId + installationId) was provided to the runtime; otherwise it throws 'GitHub receipt runtime unavailable'. It is a guard against calling a GitHub-specific mutation through a runtime configured for another provider or without receipt-apply credentials.","triggerScenarios":"Calling applyGitHubReceiptReaction when (a) this.provider !== 'github' (runtime built for slack/telegram/teams), or (b) this.githubReceiptApp is null because no GitHub App appId/installationId was supplied at runtime construction.","commonSituations":"Endpoint misconfiguration where the receipt pipeline is wired to a GitHub receipt store but the chat endpoint is Slack/Teams; missing GitHub App installation env/config (PAPERCLIP GitHub app not installed for the org); stale runtime instances created before the GitHub App was configured.","solutions":["Verify the endpoint's chat provider is actually 'github' before invoking GitHub receipt mutations","Configure the GitHub receipt App (appId + installationId) when constructing the ChatSdkRuntime so this.githubReceiptApp is populated","Check environment/config loading for the GitHub App credentials; reinstall the GitHub App installation if it was removed","Route the receipt mutation to the runtime instance matching the provider instead of the current one"],"exampleFix":"// before\nawait runtime.applyGitHubReceiptReaction(input, assertCurrent);\n// after\nif (runtime.provider === 'github') {\n  await runtime.applyGitHubReceiptReaction(input, assertCurrent);\n}","handlingStrategy":"validation","validationCode":"if (runtime.provider !== 'github') throw new Error('GitHub receipt requires a github runtime');","typeGuard":"const canApplyGitHubReceipt = (r: ChatSdkRuntime): r is ChatSdkRuntime & { provider: 'github' } => r.provider === 'github';","tryCatchPattern":"try { await runtime.applyGitHubReceiptReaction(input, assertCurrent); } catch (e) { if ((e as Error).message === 'GitHub receipt runtime unavailable') { /* route to correct provider runtime or log config gap */ } else throw e; }","preventionTips":["Match receipt mutations to the runtime provider before dispatching","Provision GitHub App appId/installationId whenever GitHub receipt endpoints are created","Add a startup check that fails fast if a github endpoint lacks receipt credentials"],"tags":["github","receipts","provider-mismatch","configuration"],"backgroundTag":"missing-required-config-field","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"}