yikart/AiToEarn · warning · AppException

ChannelPublishValidationFailed

ChannelPublishValidationFailed

Error message

ChannelPublishValidationFailed

What it means

ChannelPublishValidationFailed is thrown by DouyinOfflineQrService.prepareContent when mediaService.preparePublishContentMedia reports non-empty issues against DOUYIN_METADATA.mediaRules. Each issue is formatted with the request locale and returned as structured detail, meaning the content (text/media mix) violates Douyin's publish constraints (e.g. too many images, missing required media, unsupported attachment types).

Source

Thrown at project/aitoearn-backend/apps/aitoearn-server/src/core/channels/platforms/douyin/offline-qr/douyin-offline-qr.service.ts:96

    if (!materialGroup) {
      throw new AppException(ResponseCode.MaterialGroupNotFound)
    }

    const material = await this.materialRepo.getInfo(materialId)
    if (!material || material.groupId !== materialGroupId) {
      throw new AppException(ResponseCode.MaterialNotFound)
    }
  }

  private async prepareContent(content: PublishContentInput): Promise<PublishContentInput> {
    const prepared = await this.mediaService.preparePublishContentMedia({
      userId: '',
      content,
      mediaRules: DOUYIN_METADATA.mediaRules,
    })
    if (prepared.issues.length) {
      const locale = getLocale()
      throw new AppException(ResponseCode.ChannelPublishValidationFailed, {
        platform: AccountType.Douyin,
        accountId: '',
        issues: prepared.issues.map(issue => formatPublishValidationIssue(issue, locale)),
      })
    }
    return prepared.content
  }

  private resolvePublishType(content: PublishContentInput): PublishType {
    return content.media.some(media => this.getMediaType(media) === DouyinMediaType.Video)
      ? PublishType.VIDEO
      : PublishType.ARTICLE
  }

  private resolveRecordMedia(
    content: PublishContentInput,
    type: PublishType,
  ): { videoUrl?: string, imgUrlList?: string[] } {

View on GitHub (pinned to d3aa8bea5b)

Solutions

  1. Read the returned issues array — each entry names the violated Douyin rule and is localized via the request locale.
  2. Adjust the publish content to satisfy DOUYIN_METADATA.mediaRules (media count, types, required fields) before retrying.
  3. Validate content client-side against the platform's mediaRules metadata fetched from the capabilities API before submitting.
  4. If rules seem wrong, confirm the DOUYIN_METADATA mediaRules version matches the current platform requirements.

Example fix

// before
content = { text: 'hi', images: [1..18 imgs] } // exceeds Douyin limit -> issues thrown
// after
content = { text: 'hi', images: images.slice(0, DOUYIN_METADATA.mediaRules.maxImages) }
await offlineQr.createPublish({ materialGroupId, materialId, content })
Defensive patterns

Strategy: validation

Validate before calling

import { DOUYIN_METADATA } from './douyin.metadata'
function validateAgainstDouyinRules(content: PublishContentInput): string[] {
  const issues: string[] = []
  const rules = DOUYIN_METADATA.mediaRules
  if (content.images && rules.maxImages && content.images.length > rules.maxImages)
    issues.push(`max ${rules.maxImages} images allowed`)
  if (rules.requireMedia && !content.images?.length && !content.video)
    issues.push('media is required')
  return issues
}
// run before createPublish and fix or surface issues

Try / catch

try {
  await offlineQrService.createPublish(dto)
} catch (err) {
  if (err instanceof AppException && err.code === ResponseCode.ChannelPublishValidationFailed) {
    // err.data.issues holds localized rule violations; show them to the user
  } else throw err
}

Prevention

When it happens

Trigger: createPublish (via content()) with publish content that breaks Douyin mediaRules: exceeding the max image/video count, empty media list for a required-media type, mismatched media types (e.g. mixing video and images where disallowed), or oversized counts/attachments per the platform metadata rules.

Common situations: Client builds content for another platform's rules (e.g. 18 images) and submits to Douyin; content prepared before materials were trimmed; platform metadata updated so previously valid content is now invalid; automation scripts posting empty-content records.

Related errors


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