{"record":{"id":"ec0f3f772683dc47","repo":"gitroomhq/postiz-app","slug":"integration-not-allowed-ec0f3f","errorCode":null,"errorMessage":"Integration not allowed","messagePattern":"Integration not allowed","errorType":"http","errorClass":"HttpException","httpStatus":400,"severity":"error","filePath":"apps/backend/src/public-api/routes/v1/public.integrations.controller.ts","lineNumber":344,"sourceCode":"            }\n          : undefined,\n      }));\n  }\n\n  @Get('/social/:integration')\n  @CheckPolicies([AuthorizationActions.Create, Sections.CHANNEL])\n  async getIntegrationUrl(\n    @Param('integration') integration: string,\n    @Query('refresh') refresh: string,\n    @GetOrgFromRequest() org: Organization\n  ) {\n    Sentry.metrics.count('public_api-request', 1);\n    if (\n      !this._integrationManager\n        .getAllowedSocialsIntegrations()\n        .includes(integration)\n    ) {\n      throw new HttpException({ msg: 'Integration not allowed' }, 400);\n    }\n\n    // A provider migrated via MIGRATE_PROVIDERS reconnects through its target\n    // provider's OAuth: the callback lands on the target and the channel is\n    // migrated in place (see migrateIntegration).\n    const migrateTo = refresh\n      ? this._integrationManager.getMigrationTarget(integration)\n      : undefined;\n\n    const integrationProvider = this._integrationManager.getSocialIntegration(\n      migrateTo || integration\n    );\n\n    if (integrationProvider.externalUrl) {\n      throw new HttpException(\n        {\n          msg: 'This integration requires an external URL and is not supported via the public API',\n        },","sourceCodeStart":326,"sourceCodeEnd":362,"githubUrl":"https://github.com/gitroomhq/postiz-app/blob/0f1647f7491a217d43eb5ae7a480484bdf0aff3e/apps/backend/src/public-api/routes/v1/public.integrations.controller.ts#L326-L362","documentation":"getIntegrationUrl checks the requested integration against integrationManager.getAllowedSocialsIntegrations(); anything not in that allowlist throws 400 'Integration not allowed'. This is a static capability check, independent of the org's connected channels.","triggerScenarios":"GET on the integration URL route with a provider name that's disabled/not built in the deployment (e.g. a provider behind a feature flag, an enterprise-only integration, a typo like 'twiter', or a provider removed in that version).","commonSituations":"Typos in provider IDs; self-hosted builds where some providers are disabled by config; requesting a provider that exists in docs but isn't enabled in that deployment/version; using a legacy provider name after MIGRATE_PROVIDERS renamed it.","solutions":["Check the exact spelling/casing of the integration id against the provider list in code (getAllowedSocialsIntegrations)","Update to a version that ships the provider, or enable it via config if it's flag-gated","If the provider was migrated, use the new provider name (see migrateIntegration flow)","List available integrations via the API/endpoint if one exists instead of guessing names"],"exampleFix":"// before\nGET /public/v1/integrations/twiter/url\n\n// after\nGET /public/v1/integrations/twitter/url","handlingStrategy":"validation","validationCode":"const ALLOWED = await api.getAllowedIntegrations(); // or hardcode from docs\nif (!ALLOWED.includes(integrationId)) {\n  throw new Error(`${integrationId} is not enabled in this deployment`);\n}","typeGuard":"const isAllowedIntegration = (id: string, allowed: string[]): id is AllowedIntegration =>\n  allowed.includes(id);","tryCatchPattern":"null","preventionTips":["Use exact provider ids from the docs/code allowlist","Re-check ids after upgrading — providers get renamed/migrated","Feature-flagged providers need enabling before use"],"tags":["integrations","allowlist","validation","public-api"],"backgroundTag":"integration-not-allowed","analyzedSha":"0f1647f7491a217d43eb5ae7a480484bdf0aff3e","analyzedAt":"2026-08-27T12:09:55.020Z","schemaVersion":2},"datasetVersion":"2026-08-27T13:17:12.746Z"}