yikart/AiToEarn · error · AppException

InvalidWorkLink

InvalidWorkLink

Error message

InvalidWorkLink

What it means

getLinkInfo normalizes the given link, then extracts the TikTok video/photo id via parseTikTokVideoId. If the id can't be extracted from the resolved URL, InvalidWorkLink is thrown — the link resolved but doesn't contain a recognizable TikTok work id.

Source

Thrown at project/aitoearn-backend/apps/aitoearn-server/src/core/channels/platforms/tiktok/tiktok-work.provider.ts:59

          commentCount: video.comment_count,
          shareCount: video.share_count,
        },
      })),
      pagination: {
        mode: ChannelPaginationMode.Cursor,
        nextCursor: response.cursor === undefined ? undefined : String(response.cursor),
        hasNext: Boolean(response.has_more),
        hasPrevious: false,
        limit,
      },
    }
  }

  async getLinkInfo(input: WorkLinkInfoInput): Promise<ChannelWorkDataResult> {
    const resolvedUrl = await this.normalizeLink(input.link)
    const platformWorkId = this.parseTikTokVideoId(resolvedUrl)
    if (!platformWorkId) {
      throw new AppException(ResponseCode.InvalidWorkLink)
    }
    const contentPath = resolvedUrl.includes('/photo/') ? 'photo' : 'video'
    return {
      snapshots: [],
      work: {
        id: platformWorkId,
        url: this.buildCanonicalWorkLink(resolvedUrl, contentPath, platformWorkId),
        mediaType: contentPath,
      },
      extra: {
        resolvedUrl,
      },
    }
  }

  async getDetail(input: WorkDetailInput): Promise<ChannelWorkDataResult> {
    const response = await this.tikTokService.queryVideos(
      input.credential.accessToken,

View on GitHub (pinned to d3aa8bea5b)

Solutions

  1. Verify the resolved URL actually contains a numeric video/photo id (e.g. /video/<digits> or /photo/<digits>).
  2. Check what normalizeLink produced (enable logging on resolveRedirectUrl) — the redirect may land on a non-video page.
  3. Extend parseTikTokVideoId to cover the URL format you're seeing, or pass a canonical /video/<id> link.
  4. Ask the user to copy the standard share link from the TikTok app.

Example fix

// before
const info = await tiktokWorkProvider.getLinkInfo({ link: profileUrl })
// after
if (!/tiktok\.com\/.+\/(video|photo)\/\d+/.test(profileUrl) && !/vm\.tiktok\.com/.test(profileUrl)) {
  throw new Error('Expected a TikTok video/photo link')
}
const info = await tiktokWorkProvider.getLinkInfo({ link: profileUrl })
Defensive patterns

Strategy: validation

Validate before calling

function hasTikTokWorkId(url: string): boolean {
  return /tiktok\.com\/.+\/(?:video|photo)\/\d+/.test(url)
}
if (!hasTikTokWorkId(link) && !/vm\.tiktok\.com|vt\.tiktok\.com/.test(link)) {
  throw new Error('Provide a TikTok video/photo URL or short link')
}

Type guard

function extractTikTokVideoId(url: string): string | null {
  return url.match(/\/(?:video|photo)\/(\d+)/)?.[1] ?? null
}

Try / catch

try {
  await tiktokWorkProvider.getLinkInfo({ link })
} catch (e) {
  if (e instanceof AppException && e.code === ResponseCode.InvalidWorkLink) {
    return { ok: false, reason: 'No TikTok video/photo id found in the link' }
  }
  throw e
}

Prevention

When it happens

Trigger: Calling getLinkInfo with a TikTok URL that normalizeLink resolves successfully but parseTikTokVideoId finds no id in — e.g. profile URLs, tag pages, embed URLs, or new URL formats with an unexpected path structure.

Common situations: User pasted a TikTok profile or hashtag link; VT/short links that redirect to a page format the id parser doesn't cover; TikTok changed its canonical /video/<id> or /photo/<id> path; regionalized domains (vm.tiktokk.com typos etc.).

Related errors


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