yikart/AiToEarn · error · AppException
MaterialGroupNotFound
MaterialGroupNotFound
Error message
MaterialGroupNotFound
What it means
MaterialGroupNotFound is thrown by DouyinOfflineQrService.validateMaterial when materialGroupRepo.getInfo(materialGroupId) returns null, i.e. no material group exists for the given id. validateMaterial runs during createPublish, so publishing an offline QR with an unknown materialGroupId is rejected before any media is prepared.
Source
Thrown at project/aitoearn-backend/apps/aitoearn-server/src/core/channels/platforms/douyin/offline-qr/douyin-offline-qr.service.ts:79
queued: false,
})
return {
recordId: record.id,
status: PublishStatus.WaitingForUserAction,
userAction: {
shareId: dataOption.shareId,
schemeUrl: dataOption.schema,
shortLink: dataOption.shortLink,
expiresAt: new Date(dataOption.expiresAt),
},
}
}
private async validateMaterial(materialGroupId: string, materialId: string): Promise<void> {
const materialGroup = await this.materialGroupRepo.getInfo(materialGroupId)
if (!materialGroup) {
throw new AppException(ResponseCode.MaterialGroupNotFound)
}
const material = await this.materialRepo.getInfo(materialId)
if (!material || material.groupId !== materialGroupId) {
throw new AppException(ResponseCode.MaterialNotFound)
}
}
private async prepareContent(content: PublishContentInput): Promise<PublishContentInput> {
const prepared = await this.mediaService.preparePublishContentMedia({
userId: '',
content,
mediaRules: DOUYIN_METADATA.mediaRules,
})
if (prepared.issues.length) {
const locale = getLocale()
throw new AppException(ResponseCode.ChannelPublishValidationFailed, {
platform: AccountType.Douyin,View on GitHub (pinned to d3aa8bea5b)
Solutions
- Fetch the user's material groups via the material-group list API and use a returned _id in createPublish.
- Check that materialGroupId and materialId are not swapped in the request payload.
- If the group was deleted, recreate it or pick another group; purge stale ids from client-side cache.
- Verify the request targets the same environment/database where the group was created (staging vs production).
Example fix
// before
await offlineQr.createPublish({ materialGroupId: '64b000000000000000000000', ... }) // group deleted -> throws
// after
const groups = await materialGroupService.listMine()
await offlineQr.createPublish({ materialGroupId: groups[0]._id, materialId: validMaterialId, ... }) Defensive patterns
Strategy: validation
Validate before calling
const group = await materialGroupRepo.getInfo(materialGroupId)
if (!group) throw new Error(`material group ${materialGroupId} does not exist`)
// only then call createPublish Type guard
const isExistingGroup = async (id: string) => (await materialGroupRepo.getInfo(id)) != null
Try / catch
try {
await offlineQrService.createPublish(dto)
} catch (err) {
if (err instanceof AppException && err.code === ResponseCode.MaterialGroupNotFound) {
// prompt user to pick a valid material group
} else throw err
} Prevention
- Load material group ids from the list API rather than caching them indefinitely
- Invalidate client-side group caches after any delete/rename operation
- Never swap materialGroupId and materialId fields in request payloads
- Ensure environments (staging vs prod) are not mixing ids
When it happens
Trigger: createPublish with a materialGroupId that was deleted, belongs to another user, was never created, or is a malformed/nonexistent id; also when ids are swapped (passing materialId where group id is expected).
Common situations: Client cached a material group id that another session deleted; hardcoded ids from tests/staging used against a different database; copy-paste between materialId and materialGroupId fields; multitenancy mismatch (id from a different workspace).
Understand the failure class
Background: 'Could not be found', 'does not exist', 'not found in database': the resource-not-found family when an ID, slug, key, or URI lookup comes back empty — this error's family across 20 libraries.
Related errors
AI-assisted analysis of yikart/AiToEarn@d3aa8bea5b (2026-08-31).
Data as JSON: /api/errors/338e0d37dc737c91.
Report an issue: GitHub.