yikart/AiToEarn · error · AppException
ChannelAuthPlatformUidMissing
ChannelAuthPlatformUidMissing
Error message
ResponseCode.ChannelAuthPlatformUidMissing
What it means
DouyinAuthProvider.revoke() needs the platform user id (platformUid) to revoke the Douyin access token for that specific open_id. If input.platformUid is absent, the provider throws ChannelAuthPlatformUidMissing before making any network call, because Douyin's revoke API is per-open_id.
Source
Thrown at project/aitoearn-backend/apps/aitoearn-server/src/core/channels/platforms/douyin/douyin-auth.provider.ts:116
}
const result = await this.douyinService.refreshAccessToken(input.refreshToken)
return {
accessToken: result.accessToken,
refreshToken: result.refreshToken,
expiresAt: result.expiresAt,
scope: result.scope,
tokenType: 'Bearer',
raw: {
refreshExpiresAt: result.refreshExpiresAt,
},
}
}
async revoke(input: RevokeCredentialInput): Promise<void> {
if (!input.platformUid) {
throw new AppException(ResponseCode.ChannelAuthPlatformUidMissing)
}
await this.douyinService.revokeAccessToken(input.accessToken, input.platformUid)
}
async getProfile(input: CredentialContext): Promise<PlatformAccountProfile> {
if (!input.platformUid) {
throw new AppException(ResponseCode.ChannelAuthPlatformUidMissing)
}
const userInfo = await this.douyinService.getUserInfo(input.accessToken, input.platformUid)
return {
platformUid: input.platformUid,
displayName: userInfo.nickname ?? '',
avatarUrl: userInfo.avatar,
raw: {
openId: userInfo.openId,View on GitHub (pinned to d3aa8bea5b)
Solutions
- Fetch the profile first (getProfile) to resolve platformUid, then call revoke with the complete input.
- Backfill platformUid on existing credential records from stored account profile data.
- If platformUid is unrecoverable, treat the token as orphaned: mark the channel disconnected locally and let the token expire.
Example fix
// before
await douyinAuth.revoke({ accessToken })
// after
const profile = await douyinAuth.getProfile({ accessToken, platformUid })
await douyinAuth.revoke({ accessToken, platformUid: profile.platformUid }) Defensive patterns
Strategy: validation
Validate before calling
if (!input.platformUid) {
// resolve before revoke
const profile = await douyinAuth.getProfile({ accessToken: input.accessToken, platformUid: storedUid })
input = { ...input, platformUid: profile.platformUid }
}
await douyinAuth.revoke(input) Type guard
function isRevocable(input: Partial<RevokeCredentialInput>): input is RevokeCredentialInput {
return typeof input.accessToken === 'string' && typeof input.platformUid === 'string' && input.platformUid.length > 0
} Try / catch
try {
await douyinAuth.revoke(input)
} catch (e) {
if (e.code === 'ChannelAuthPlatformUidMissing') {
// token is orphaned; disconnect locally and let it expire
await markChannelDisconnected(channelId)
} else throw e
} Prevention
- Store platformUid on the credential at connect time, next to the token.
- Never construct revoke inputs by hand from partial records — load the full credential.
- Treat missing platformUid as an unrecoverable credential and flag for re-auth.
When it happens
Trigger: Calling revoke (e.g. disconnecting a Douyin channel or admin cleanup) with a RevokeCredentialInput that lacks platformUid — the credential record never stored the platform user id.
Common situations: Legacy channel rows created before platformUid was persisted, credentials built from a flow that skipped profile fetching, or callers constructing the revoke input manually from partial data.
Related errors
- ChannelAuthRefreshTokenMissing
- ChannelAccessTokenFailed
- ChannelAuthorizationFailed
- ChannelAuthCsrfInvalid
- ChannelAuthCodeMissing
AI-assisted analysis of yikart/AiToEarn@d3aa8bea5b (2026-08-31).
Data as JSON: /api/errors/3bc1cd2449c11215.
Report an issue: GitHub.