yikart/AiToEarn · error · AppException
InvalidWorkLink
InvalidWorkLink
Error message
InvalidWorkLink
What it means
RedNote publish requires input.option.workLink: without it there is no source note to publish from, so the provider throws InvalidWorkLink before doing any work. It is a synchronous input-validation error thrown from the publish entry point.
Source
Thrown at project/aitoearn-backend/apps/aitoearn-server/src/core/channels/platforms/rednote/rednote-publish.provider.ts:66
params: { field: PublishValidationField.Option },
}],
}
}
return { valid: true }
}
async normalize(input: PublishNormalizeInput<RedNoteOption>): Promise<NormalizedPublishTask<RedNoteOption>> {
return {
content: input.content,
option: input.option,
}
}
async publish(input: PublishPublishInput<RedNoteOption>): Promise<PublishProviderResult<RedNoteDataOption>> {
const workLink = input.option?.workLink
if (!workLink) {
throw new AppException(ResponseCode.InvalidWorkLink)
}
const workLinkInfo = await this.workProvider.getWorkLinkInfo(workLink)
const extra = workLinkInfo.extra
return {
status: 200,
platformWorkId: extra.dataId,
permalink: extra.resolvedUrl ?? workLink,
originalWorkLink: extra.originalWorkLink,
workStatus: extra.workStatus,
dataOption: {
dataId: extra.dataId,
uniqueId: extra.uniqueId,
},
}
}
}View on GitHub (pinned to d3aa8bea5b)
Solutions
- Ensure the publishing request includes option.workLink with the full RedNote note URL.
- Validate the input payload at the API/job boundary before invoking publish (require non-empty workLink for RedNote).
- Check where the PublishPublishInput is constructed in your flow — the workLink is likely dropped during serialization or option construction.
Example fix
// before
await provider.publish({ ...rest, option: undefined })
// after
if (!rest.option?.workLink) {
throw new Error('RedNote publish requires option.workLink')
}
await provider.publish({ ...rest, option: rest.option }) Defensive patterns
Strategy: validation
Validate before calling
function assertRedNotePublishInput(input: PublishPublishInput<RedNoteOption>) {
if (!input.option?.workLink) {
throw new Error('RedNote publish requires a non-empty option.workLink')
}
} Type guard
function hasWorkLink(opt: RedNoteOption | undefined | null): opt is RedNoteOption & { workLink: string } {
return typeof opt?.workLink === 'string' && opt.workLink.length > 0
} Try / catch
try {
await provider.publish(input)
} catch (e) {
if (e instanceof AppException && e.code === ResponseCode.InvalidWorkLink) {
return { ok: false, reason: 'missing workLink in publish option' }
}
throw e
} Prevention
- Validate publish payloads against a schema (zod/class-validator) at the API boundary.
- Make workLink a required field in the RedNote publish DTO.
- Add a unit test asserting publish throws without workLink.
- Check serialization of options when queuing publish jobs.
When it happens
Trigger: Calling rednotePublishProvider.publish with input.option undefined, or option present but option.workLink missing/null/empty.
Common situations: Caller builds PublishPublishInput without populating the RedNote-specific option; upstream job lost the workLink field; caller confused workLink with a plain note URL stored elsewhere; schema change on the producer side dropped the field.
Understand the failure class
Background: "Missing required field" and "field is required" errors: why libraries reject payloads that omit mandatory fields — this error's family across 20 libraries.
Related errors
- InvalidWorkLink
- ChannelPublishPlatformWorkIdMissing
- accountId和publishId是必须的
- ChannelPlatformMediaUnsupported
- No subtitle entries in response
AI-assisted analysis of yikart/AiToEarn@d3aa8bea5b (2026-08-31).
Data as JSON: /api/errors/7332337a47537cff.
Report an issue: GitHub.