yikart/AiToEarn · error · AppException

ChannelWebhookNotSupported

ChannelWebhookNotSupported

Error message

ChannelWebhookNotSupported

What it means

dispatchWebhook routes an inbound HTTP webhook (method + originalUrl) to the platform's registered PlatformWebhookHandler. When registry.getWebhook(platform) returns undefined — the platform exists but registered no webhook handler — the service logs a warning and throws ChannelWebhookNotSupported with the platform in the details. It means this platform's integration cannot process callbacks at that URL.

Solutions

  1. Verify the callback URL configured on the external platform matches a platform that registers a webhook handler; correct the configuration on the provider's developer console.
  2. Check capabilities.webhook.supported in the platform metadata before exposing or advertising a webhook URL for that platform.
  3. If the platform should receive webhooks, implement PlatformWebhookHandler and set integration.webhook in the integration.
  4. At the HTTP edge, return a clear 4xx for this code and avoid retries from the upstream provider.

Example fix

// before
webhookUrl = `${baseUrl}/api/webhooks/${platform}` // assumed all platforms support it
// after
if (!platformMeta.webhook.supported) {
  throw new Error(`${platform} does not support webhooks`)
}
webhookUrl = `${baseUrl}/api/webhooks/${platform}`
Defensive patterns

Strategy: validation

Validate before calling

const meta = platformMetadata[platform]
if (!meta?.webhook.supported) {
  throw new BadRequestException(`${platform} has no webhook handler`)
}

Type guard

function hasWebhookHandler(integration: PlatformIntegration): integration is PlatformIntegration & { webhook: PlatformWebhookHandler } {
  return Boolean(integration.webhook)
}

Try / catch

try {
  return await webhookService.dispatch(platform, request)
} catch (e) {
  if (e instanceof AppException && e.code === ResponseCode.ChannelWebhookNotSupported) {
    reply.code(404).send({ error: `No webhook handler for ${e.details.platform}` })
    return
  }
  throw e
}

Prevention

When it happens

Trigger: Configuring an external platform's webhook/callback URL to point at this service for a platform whose integration has no webhook handler, or an external system POSTing callback events for a platform integrated without webhook support; any method/URL dispatched to the platform webhook route that resolves to a null handler.

Common situations: Copy-pasting a webhook configuration (e.g. Meta-style callback URLs) across platforms; the platform integration's webhook handler removed or feature-flagged off; scammers/bots probing the webhook endpoint with arbitrary platform paths.

Related errors


AI-assisted analysis of yikart/AiToEarn@d3aa8bea5b (2026-08-31). Data as JSON: /api/errors/f042977e3a6c01c5. Report an issue: GitHub.

Appendix: source

Thrown at project/aitoearn-backend/apps/aitoearn-server/src/core/channels/platforms/platforms.service.ts:98

      data: parsedData,
      credential: {
        accessToken: credential.accessToken,
        refreshToken: credential.refreshToken,
        platformUid: account.uid,
        account: account.account,
      },
    }))
  }

  async dispatchWebhook(platform: AccountType, request: Request, response: Response): Promise<void> {
    const handler = this.registry.getWebhook(platform)
    if (!handler) {
      this.logger.warn({
        platform,
        method: request.method,
        url: request.originalUrl,
      }, 'Webhook is not supported by platform')
      throw new AppException(ResponseCode.ChannelWebhookNotSupported, { platform })
    }

    this.logger.log({
      platform,
      method: request.method,
      url: request.originalUrl,
    }, 'Dispatching platform webhook')
    await handler.handle(request, response, { platform })
    if (!response.headersSent) {
      const exception = new ChannelPlatformException({
        code: ResponseCode.ChannelWebhookPublishFailed,
        platform,
        category: PlatformErrorCategory.WebhookInvalid,
        context: {
          method: request.method,
          endpoint: request.originalUrl,
        },
        cause: {

View on GitHub (pinned to d3aa8bea5b)