yikart/AiToEarn · error · AppException
ChannelPlatformResponseInvalid
ChannelPlatformResponseInvalid
Error message
ChannelPlatformResponseInvalid
What it means
ChannelPlatformResponseInvalid is thrown by DouyinOfflineQrService.createPublish when the handoff publish result from the Douyin publish provider is incomplete: platformWorkId, dataOption.schema, dataOption.shortLink, or dataOption.expiresAt is missing after parseDouyinDataOption. The offline-QR flow requires all four fields to build a scannable, expiring QR share record, so any missing piece invalidates the whole response.
Source
Thrown at project/aitoearn-backend/apps/aitoearn-server/src/core/channels/platforms/douyin/offline-qr/douyin-offline-qr.service.ts:33
constructor(
private readonly publishRecordRepo: PublishRecordRepository,
private readonly materialGroupRepo: MaterialGroupRepository,
private readonly materialRepo: MaterialRepository,
private readonly douyinPublishProvider: DouyinPublishProvider,
private readonly mediaService: MediaService,
) {}
async createPublish(dto: CreateDouyinOfflineQrPublishDto) {
await this.validateMaterial(dto.materialGroupId, dto.materialId)
const content = await this.prepareContent(dto.content)
const result = await this.douyinPublishProvider.createHandoffPublishResult({
content,
option: dto.option,
})
const dataOption = parseDouyinDataOption(result.dataOption)
if (!result.platformWorkId || !dataOption?.schema || !dataOption.shortLink || !dataOption.expiresAt) {
throw new AppException(ResponseCode.ChannelPlatformResponseInvalid, { platform: AccountType.Douyin })
}
const type = this.resolvePublishType(content)
const media = this.resolveRecordMedia(content, type)
const record = await this.publishRecordRepo.create({
userId: '',
accountId: '',
uid: '',
materialGroupId: dto.materialGroupId,
materialId: dto.materialId,
accountType: AccountType.Douyin,
type,
status: PublishStatus.WaitingForUserAction,
title: content.title,
desc: content.body,
topics: parseTopicsFromBody(content.body),
publishTime: new Date(),
source: dto.source ?? PublishRecordSource.OfflineQr,View on GitHub (pinned to d3aa8bea5b)
Solutions
- Log the raw provider result and check which field is missing (platformWorkId vs schema vs shortLink vs expiresAt) to target the real failure.
- Verify the Douyin app has share/schema permissions and valid client credentials so generateShareSchema produces a full schema URL.
- Confirm parseDouyinDataOption still matches the current Douyin dataOption format (update after platform API changes).
- Retry the createPublish call; transient upstream share-id failures often succeed on a second attempt.
Example fix
// before
const result = await provider.createHandoffPublishResult(...) // dataOption lacks expiresAt -> throws
// after
// ensure upstream returns full schema with expiry
const schema = await douyinService.generateShareSchema({ shareId, private_status: 0 })
// provider now returns dataOption.schema/shortLink/expiresAt -> createPublish succeeds Defensive patterns
Strategy: try-catch
Type guard
function isValidHandoffResult(r: { platformWorkId?: string; dataOption?: unknown } | null)
: r is { platformWorkId: string; dataOption: { schema: string; shortLink: string; expiresAt: unknown } } {
const d = parseDouyinDataOption(r?.dataOption)
return !!r?.platformWorkId && !!d?.schema && !!d?.shortLink && d?.expiresAt != null
} Try / catch
try {
const record = await offlineQrService.createPublish(dto)
} catch (err) {
if (err instanceof AppException && err.code === ResponseCode.ChannelPlatformResponseInvalid) {
// log raw provider result for which field was missing, retry once before surfacing
} else throw err
} Prevention
- Verify the Douyin app's share/schema permissions so full dataOption is always returned
- Keep parseDouyinDataOption in sync with current Douyin dataOption format
- Log raw provider results on failure to identify the missing field quickly
- Preflight the share-id/ticket chain before starting offline-QR publish flows
When it happens
Trigger: Calling createPublish on the offline-QR service when the underlying Douyin share handoff (getShareid/generateShareSchema chain) yields a result whose dataOption cannot be parsed or lacks schema/shortLink/expiresAt — e.g. the share-id request failed upstream, or the schema URL generation returned an empty/short form.
Common situations: Douyin platform returning degraded share-id data; app credentials valid but share schema permission missing so schema generation is skipped; changes in Douyin's dataOption format breaking parseDouyinDataOption; transient upstream failure cached and surfaced here.
Related errors
- ChannelPlatformApiFailed
- 获取三方平台数据失败
- ChannelPlatformMediaProcessingFailed
- ChannelAuthRefreshTokenMissing
- ChannelAuthPlatformUidMissing
AI-assisted analysis of yikart/AiToEarn@d3aa8bea5b (2026-08-31).
Data as JSON: /api/errors/4d4d1f30e3e07316.
Report an issue: GitHub.