{"record":{"id":"a42904737c72e98e","repo":"yikart/AiToEarn","slug":"invalidworklink-a42904","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/facebook/facebook-work.provider.ts","lineNumber":94,"sourceCode":"      || this.isImageType(attachment.type)\n      || this.hasImageAttachment(attachment.subattachments?.data),\n    ) ?? false\n  }\n\n  private isVideoType(type?: string): boolean {\n    return !!type && type.toLowerCase().includes('video')\n  }\n\n  private isImageType(type?: string): boolean {\n    const normalized = type?.toLowerCase()\n    return normalized === 'photo' || normalized === 'image'\n  }\n\n  async getLinkInfo(input: WorkLinkInfoInput): Promise<ChannelWorkDataResult> {\n    const resolvedUrl = await this.normalizeLink(input.link)\n    const platformWorkId = this.parseFacebookWorkId(resolvedUrl)\n    if (!platformWorkId) {\n      throw new AppException(ResponseCode.InvalidWorkLink)\n    }\n    return {\n      snapshots: [],\n      work: {\n        id: platformWorkId,\n        url: resolvedUrl,\n      },\n    }\n  }\n\n  async getDetail(input: WorkDetailInput): Promise<ChannelWorkDataResult> {\n    const post = await this.facebookService.getPostInfo(\n      input.credential.accessToken,\n      input.platformWorkId,\n    )\n    const fetchedAt = new Date()\n    const createdAt = post.createdTime ? new Date(post.createdTime) : undefined\n    const snapshot = {","sourceCodeStart":76,"sourceCodeEnd":112,"githubUrl":"https://github.com/yikart/AiToEarn/blob/d3aa8bea5b146a8675607cf0144d891aad3e9683/project/aitoearn-backend/apps/aitoearn-server/src/core/channels/platforms/facebook/facebook-work.provider.ts#L76-L112","documentation":"getLinkInfo could not extract a Facebook work id from the normalized link. The URL resolved fine but parseFacebookWorkId returned null, meaning the link is not a recognized Facebook post/video/reel URL pattern.","triggerScenarios":"Calling getLinkInfo with input.link that, after normalizeLink, contains no Facebook work id pattern (e.g. a facebook.com profile URL, a share link variant not supported by the regex, or a non-Facebook URL).","commonSituations":"Users paste mobile (m.facebook.com) or locale-prefixed links, share redirects, story links, or truncated URLs; plugin regex doesn't cover the newer /share/v/ or /reel/ formats.","solutions":["Check the link is a supported Facebook post/video/reel permalink","Ask the user to copy the canonical permalink (facebook.com/<page>/posts/<id> or /videos/<id>)","Update parseFacebookWorkId to support the URL variant being pasted","Log resolvedUrl to confirm what pattern reaches the parser"],"exampleFix":null,"handlingStrategy":"validation","validationCode":"const FB_WORK_RE = /facebook\\.com\\/(?:[^/]+\\/(?:posts|videos|reels)\\/\\d+|watch\\/?\\?v=\\d+|reel\\/\\d+)/\nif (!FB_WORK_RE.test(input.link)) {\n  throw new Error('Not a supported Facebook work link')\n}","typeGuard":"function isFacebookWorkUrl(url: string): boolean {\n  try { const u = new URL(url); return /(^|\\.)facebook\\.com$/.test(u.hostname) && /\\d{5,}/.test(u.pathname + u.search) } catch { return false }\n}","tryCatchPattern":null,"preventionTips":["Validate links in the UI before submission with the same regex family the provider uses","Show users an example of an accepted Facebook permalink","Keep the parser regex in sync with new Facebook share formats","Normalize m.facebook.com and locale prefixes before parsing"],"tags":["facebook","url-parsing","link","validation"],"backgroundTag":"unsupported-work-link","analyzedSha":"d3aa8bea5b146a8675607cf0144d891aad3e9683","analyzedAt":"2026-08-31T14:19:24.185Z","schemaVersion":2},"datasetVersion":"2026-08-31T19:17:28.585Z"}