yikart/AiToEarn · error · AppException

InvalidWorkLink

InvalidWorkLink

Error message

ResponseCode.InvalidWorkLink

What it means

BilibiliWorkProvider.getLinkInfo normalizes the given work link and tries to extract a Bilibili video ID (BV/av). If parseVideoId returns null the link is not a recognizable Bilibili video URL, so it throws AppException InvalidWorkLink.

Source

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

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'

@Injectable()
export class BilibiliWorkProvider implements WorkProvider {
  readonly requiresCredentialForLinkInfo = false
  private readonly logger = new Logger(BilibiliWorkProvider.name)

  async getLinkInfo(input: WorkLinkInfoInput): Promise<ChannelWorkDataResult> {
    const resolvedUrl = await this.normalizeLink(input.link)
    const dataId = this.parseVideoId(resolvedUrl)
    if (!dataId) {
      throw new AppException(ResponseCode.InvalidWorkLink)
    }

    const url = `https://www.bilibili.com/video/${dataId}`
    return {
      snapshots: [],
      work: {
        id: dataId,
        url,
        mediaType: PublishType.VIDEO,
      },
      extra: {
        dataId,
        uniqueId: `${AccountType.Bilibili}_${dataId}`,
        type: PublishType.VIDEO,
        videoType: 'long',
        resolvedUrl: url,
      },
      rawResponse: { resolvedUrl },

View on GitHub (pinned to d3aa8bea5b)

Solutions

  1. Validate the URL resolves to a /video/BV... or /video/av... path before calling getLinkInfo.
  2. Ask the user to paste the canonical video URL (www.bilibili.com/video/BV...).
  3. Update normalizeLink/parseVideoId regexes if Bilibili introduced new valid URL formats.
  4. Catch InvalidWorkLink and return 'this link is not a Bilibili video' to the caller.

Example fix

// before
await workProvider.getLinkInfo({ link: 'https://www.bilibili.com/space/xyz' })

// after
const m = link.match(/bilibili\.com\/video\/(BV[\w]+|av\d+)/)
if (!m) throw new InvalidWorkLink()
await workProvider.getLinkInfo({ link })
Defensive patterns

Strategy: validation

Validate before calling

const VIDEO_RE = /^https?:\/\/(www\.)?bilibili\.com\/video\/(BV[\w]+|av\d+)/i
if (!VIDEO_RE.test(link) && !/^https?:\/\/b23\.tv\//.test(link)) {
  throw new Error('Not a Bilibili video link')
}

Type guard

function isBilibiliVideoUrl(url: string): boolean {
  return /bilibili\.com\/video\/(BV[\w]+|av\d+)/i.test(url)
}

Try / catch

try {
  info = await workProvider.getLinkInfo({ link })
} catch (e) {
  if (e.code === 'InvalidWorkLink') return { error: '请粘贴 B 站视频链接(/video/BV...)' }
  throw e
}

Prevention

When it happens

Trigger: getLinkInfo called with a link that, after normalizeLink/redirect resolution, does not match Bilibili video URL patterns (no BVxxx/avxxx ID), e.g. a space/album/article/live URL or an unrelated site URL.

Common situations: User pastes a mobile share link whose redirect target is not a video page; URL contains b23.tv short link that resolves to a non-video page; malformed/truncated URL; platform changed URL format.

Related errors


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