yikart/AiToEarn · error · AppException
InvalidWorkLink
InvalidWorkLink
Error message
InvalidWorkLink
What it means
getWorkLinkInfo parses the RedNote URL to extract a noteId, optionally falling back to the dataId argument. If neither parseRedNoteUrl yields a noteId nor a dataId is supplied, the link cannot be identified and InvalidWorkLink is thrown.
Source
Thrown at project/aitoearn-backend/apps/aitoearn-server/src/core/channels/platforms/rednote/rednote-work.provider.ts:32
workStatus?: WorkStatus
} & Record<string, string | PublishType | WorkStatus | undefined>
export type RedNoteWorkLinkInfoResult = ChannelWorkDataResult<RedNoteWorkLinkExtra> & { extra: RedNoteWorkLinkExtra }
@Injectable()
export class RedNoteWorkProvider implements WorkProvider {
readonly requiresCredentialForLinkInfo = false
private readonly logger = new Logger(RedNoteWorkProvider.name)
async getLinkInfo(input: WorkLinkInfoInput): Promise<ChannelWorkDataResult> {
return this.getWorkLinkInfo(input.link, input.dataId)
}
async getWorkLinkInfo(workLink: string, dataId?: string): Promise<RedNoteWorkLinkInfoResult> {
const parsed = await this.parseRedNoteUrl(workLink)
const resolvedDataId = parsed.noteId || dataId || ''
if (!resolvedDataId) {
throw new AppException(ResponseCode.InvalidWorkLink)
}
const resolvedUrl = parsed.resolvedUrl ?? workLink
const extra: RedNoteWorkLinkExtra = {
dataId: resolvedDataId,
uniqueId: `${AccountType.RedNote}_${resolvedDataId}`,
type: PublishType.VIDEO,
videoType: 'short',
resolvedUrl,
originalWorkLink: resolvedUrl !== workLink ? workLink : undefined,
workStatus: parsed.noteId && !parsed.xsecToken ? WorkStatus.LINK_ERROR : undefined,
}
return {
work: {
id: resolvedDataId,
url: resolvedUrl,
mediaType: PublishType.VIDEO,View on GitHub (pinned to d3aa8bea5b)
Solutions
- Verify the input is a direct RedNote note URL containing a note id (e.g. xiaohongshu.com/explore/<id> or /discovery/item/<id>).
- If you have the note id from another source, pass it as the dataId argument so the parse result isn't required.
- Inspect parseRedNoteUrl's accepted URL patterns and normalize the user-supplied share text/short link to a supported format before calling.
- Ask the user to re-copy the share link via the RedNote app's 'copy link' action.
Example fix
// before
const info = await workProvider.getWorkLinkInfo(userInput)
// after
const noteId = userInput.match(/(?:explore|discovery\/item)\/([0-9a-f]+)/)?.[1]
if (!noteId) throw new Error('Not a RedNote note link')
const info = await workProvider.getWorkLinkInfo(userInput, noteId) Defensive patterns
Strategy: validation
Validate before calling
const NOTE_ID_RE = /(?:explore|discovery\/item)\/([0-9a-zA-Z]+)/
function isRedNoteNoteLink(link: string): boolean {
return NOTE_ID_RE.test(link)
}
if (!isRedNoteNoteLink(link) && !dataId) throw new Error('Provide a RedNote note URL or a dataId') Type guard
function isRedNoteNoteLink(link: string): link is string {
return /xiaohongshu\.com\/.+(?:explore|discovery\/item)\/[0-9a-zA-Z]+/.test(link)
} Try / catch
try {
await workProvider.getWorkLinkInfo(link)
} catch (e) {
if (e instanceof AppException && e.code === ResponseCode.InvalidWorkLink) {
return { ok: false, reason: 'URL is not a RedNote note link and no dataId was provided' }
}
throw e
} Prevention
- Pre-validate user-pasted URLs against the known note URL patterns.
- Normalize share texts/short links before calling getWorkLinkInfo.
- Pass the extracted note id as dataId when available.
- Reject non-note URLs (profile/search/homepage) at the UI layer.
When it happens
Trigger: Calling getWorkLinkInfo (directly or via getLinkInfo) with a string that is not a recognizable RedNote note URL (no note id in path/query), and no dataId fallback passed.
Common situations: User pasted a RedNote homepage/profile/search URL instead of a note link; short-link or share-text format that parseRedNoteUrl doesn't handle; link to a deleted/private note that returns no id; mobile share URL variant not matching the parse regex.
Related errors
AI-assisted analysis of yikart/AiToEarn@d3aa8bea5b (2026-08-31).
Data as JSON: /api/errors/33bc3591841cd38f.
Report an issue: GitHub.