{"record":{"id":"f5ba309fcb9f6910","repo":"yikart/AiToEarn","slug":"invalidworklink-f5ba30","errorCode":"InvalidWorkLink","errorMessage":"InvalidWorkLink","messagePattern":"InvalidWorkLink","errorType":"error_code","errorClass":"AppException","httpStatus":null,"severity":"error","filePath":"project/aitoearn-backend/apps/aitoearn-server/src/core/channels/platforms/tiktok/tiktok-work.provider.ts","lineNumber":59,"sourceCode":"          commentCount: video.comment_count,\n          shareCount: video.share_count,\n        },\n      })),\n      pagination: {\n        mode: ChannelPaginationMode.Cursor,\n        nextCursor: response.cursor === undefined ? undefined : String(response.cursor),\n        hasNext: Boolean(response.has_more),\n        hasPrevious: false,\n        limit,\n      },\n    }\n  }\n\n  async getLinkInfo(input: WorkLinkInfoInput): Promise<ChannelWorkDataResult> {\n    const resolvedUrl = await this.normalizeLink(input.link)\n    const platformWorkId = this.parseTikTokVideoId(resolvedUrl)\n    if (!platformWorkId) {\n      throw new AppException(ResponseCode.InvalidWorkLink)\n    }\n    const contentPath = resolvedUrl.includes('/photo/') ? 'photo' : 'video'\n    return {\n      snapshots: [],\n      work: {\n        id: platformWorkId,\n        url: this.buildCanonicalWorkLink(resolvedUrl, contentPath, platformWorkId),\n        mediaType: contentPath,\n      },\n      extra: {\n        resolvedUrl,\n      },\n    }\n  }\n\n  async getDetail(input: WorkDetailInput): Promise<ChannelWorkDataResult> {\n    const response = await this.tikTokService.queryVideos(\n      input.credential.accessToken,","sourceCodeStart":41,"sourceCodeEnd":77,"githubUrl":"https://github.com/yikart/AiToEarn/blob/d3aa8bea5b146a8675607cf0144d891aad3e9683/project/aitoearn-backend/apps/aitoearn-server/src/core/channels/platforms/tiktok/tiktok-work.provider.ts#L41-L77","documentation":"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.","triggerScenarios":"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.","commonSituations":"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.).","solutions":["Verify the resolved URL actually contains a numeric video/photo id (e.g. /video/<digits> or /photo/<digits>).","Check what normalizeLink produced (enable logging on resolveRedirectUrl) — the redirect may land on a non-video page.","Extend parseTikTokVideoId to cover the URL format you're seeing, or pass a canonical /video/<id> link.","Ask the user to copy the standard share link from the TikTok app."],"exampleFix":"// before\nconst info = await tiktokWorkProvider.getLinkInfo({ link: profileUrl })\n// after\nif (!/tiktok\\.com\\/.+\\/(video|photo)\\/\\d+/.test(profileUrl) && !/vm\\.tiktok\\.com/.test(profileUrl)) {\n  throw new Error('Expected a TikTok video/photo link')\n}\nconst info = await tiktokWorkProvider.getLinkInfo({ link: profileUrl })","handlingStrategy":"validation","validationCode":"function hasTikTokWorkId(url: string): boolean {\n  return /tiktok\\.com\\/.+\\/(?:video|photo)\\/\\d+/.test(url)\n}\nif (!hasTikTokWorkId(link) && !/vm\\.tiktok\\.com|vt\\.tiktok\\.com/.test(link)) {\n  throw new Error('Provide a TikTok video/photo URL or short link')\n}","typeGuard":"function extractTikTokVideoId(url: string): string | null {\n  return url.match(/\\/(?:video|photo)\\/(\\d+)/)?.[1] ?? null\n}","tryCatchPattern":"try {\n  await tiktokWorkProvider.getLinkInfo({ link })\n} catch (e) {\n  if (e instanceof AppException && e.code === ResponseCode.InvalidWorkLink) {\n    return { ok: false, reason: 'No TikTok video/photo id found in the link' }\n  }\n  throw e\n}","preventionTips":["Accept only /video/<id> or /photo/<id> canonical URLs, or recognized short links.","Reject profile/hashtag/embed URLs at the UI before calling the provider.","Keep parseTikTokVideoId updated for new TikTok path formats.","Ask users to use the app's native share-link copy action."],"tags":["validation","url-parsing","tiktok"],"backgroundTag":"invalid-url","analyzedSha":"d3aa8bea5b146a8675607cf0144d891aad3e9683","analyzedAt":"2026-08-31T14:19:24.185Z","schemaVersion":2},"datasetVersion":"2026-08-31T22:30:34.772Z"}