yikart/AiToEarn · warning · AppException
InvalidWorkLink
InvalidWorkLink
Error message
InvalidWorkLink
What it means
getLinkInfo parses a Douyin work (video) link and throws InvalidWorkLink when parseWorkId cannot extract a data/work ID from the normalized URL. It means the provided link is not a recognized Douyin work URL.
Source
Thrown at project/aitoearn-backend/apps/aitoearn-server/src/core/channels/platforms/douyin/douyin-work.provider.ts:17
import type { ChannelWorkDataResult, WorkLinkInfoInput, WorkProvider } from '../platforms.interface'
import { Injectable, Logger } from '@nestjs/common'
import { PublishType } from '@yikart/aitoearn-server-shared'
import { AccountType, AppException, ResponseCode } from '@yikart/common'
import axios from 'axios'
import { buildDouyinVideoWorkLink } from './douyin.interface'
@Injectable()
export class DouyinWorkProvider implements WorkProvider {
readonly requiresCredentialForLinkInfo = false
private readonly logger = new Logger(DouyinWorkProvider.name)
async getLinkInfo(input: WorkLinkInfoInput): Promise<ChannelWorkDataResult> {
const resolvedUrl = await this.normalizeLink(input.link)
const dataId = this.parseWorkId(resolvedUrl)
if (!dataId) {
throw new AppException(ResponseCode.InvalidWorkLink)
}
const url = this.buildWorkLink(dataId, resolvedUrl)
return {
snapshots: [],
work: {
id: dataId,
url,
mediaType: PublishType.VIDEO,
},
extra: {
dataId,
uniqueId: `${AccountType.Douyin}_${dataId}`,
type: PublishType.VIDEO,
videoType: 'short',
resolvedUrl: url,
},
rawResponse: { resolvedUrl },View on GitHub (pinned to d3aa8bea5b)
Solutions
- Verify the input is a direct Douyin work URL (video detail page containing the work ID)
- Extend normalizeLink/parseWorkId regexes to handle the new share-link format seen in production
- Ask the user to re-share via the app's 'copy link' so the URL contains the work ID
Example fix
// before
const dataId = this.parseWorkId(resolvedUrl)
if (!dataId) {
throw new AppException(ResponseCode.InvalidWorkLink)
}
// after
const dataId = this.parseWorkId(resolvedUrl)
if (!dataId) {
throw new AppException(ResponseCode.InvalidWorkLink, { url: resolvedUrl })
} Defensive patterns
Strategy: validation
Validate before calling
const DOUYIN_WORK_URL = /douyin\.com\/(video|note)\/(\d+)/
export function extractWorkId(link: string): string | null {
const m = link.match(DOUYIN_WORK_URL) ?? link.match(/douyin\.com.*[?&]modal_id=(\d+)/)
return m ? m[1] : null
}
if (!extractWorkId(userLink)) {
return { ok: false, message: 'Please share a direct Douyin video link' }
} Type guard
function isDouyinWorkUrl(url: string): boolean {
return /douyin\.com\/(video|note)\/\d+/.test(url) || /modal_id=\d+/.test(url)
} Try / catch
try {
const info = await workProvider.getLinkInfo({ link })
} catch (e) {
if (e instanceof AppException && e.code === 'InvalidWorkLink') {
return { ok: false, userMessage: 'This does not look like a Douyin video link. Use share > copy link.' }
}
throw e
} Prevention
- Validate links client-side with a regex before calling the API
- Normalize share text (extract the URL from v.douyin.com short links) before parsing
- Add regression tests for new Douyin share-link formats reported by users
- Show users an example of an acceptable link when validation fails
When it happens
Trigger: Calling getLinkInfo with a URL whose normalized form doesn't match Douyin work-URL patterns (e.g. user profile page, short-share URL that normalizeLink couldn't resolve, or non-Douyin link).
Common situations: Users pasting share text instead of a URL, new Douyin share-link formats the parser doesn't recognize, shortened links requiring an HTTP resolution step that failed or was skipped, or private/deleted works whose pages no longer resolve to an ID.
Related errors
AI-assisted analysis of yikart/AiToEarn@d3aa8bea5b (2026-08-31).
Data as JSON: /api/errors/11ab821d68b9e65f.
Report an issue: GitHub.