{"record":{"id":"058dfe71645206a5","repo":"yikart/AiToEarn","slug":"channelplatformmediaprocessingfailed-058dfe","errorCode":"ChannelPlatformMediaProcessingFailed","errorMessage":"ResponseCode.ChannelPlatformMediaProcessingFailed","messagePattern":"ResponseCode\\.ChannelPlatformMediaProcessingFailed","errorType":"exception","errorClass":"BilibiliPlatformException","httpStatus":null,"severity":"error","filePath":"project/aitoearn-backend/apps/aitoearn-server/src/core/channels/platforms/bilibili/bilibili.service.ts","lineNumber":354,"sourceCode":"  async uploadCover(\n    accessToken: string,\n    coverUrl: string,\n  ): Promise<string> {\n    const coverBuffer = await this.mediaService.getBuffer({\n      platform: AccountType.Bilibili,\n      endpoint: 'downloadCover',\n      url: coverUrl,\n    })\n\n    const formData = new FormData()\n    formData.append('file', new Blob([new Uint8Array(coverBuffer)]), this.resolveFileName(coverUrl, 'cover.jpg'))\n\n    const response = await this.platformHttp.post<BilibiliApiResponse<{ url: string }>>(`${this.openBaseUrl}/arcopen/fn/archive/cover/upload`, formData, {\n      headers: this.buildSignedHeaders(accessToken, '', 'multipart/form-data'),\n    })\n\n    if (!response.data.data?.url) {\n      throw new BilibiliPlatformException({\n        code: ResponseCode.ChannelPlatformMediaProcessingFailed,\n        category: PlatformErrorCategory.MediaProcessingFailed,\n        context: { endpoint: 'POST /arcopen/fn/archive/cover/upload' },\n        cause: { type: PlatformErrorCauseType.Platform },\n      })\n    }\n\n    return response.data.data.url\n  }\n\n  async getArchiveDetail(\n    accessToken: string,\n    bvid: string,\n  ): Promise<BilibiliArchiveDetail> {\n    const data = await this.signedRequest<{\n      resource_id: string\n      title: string\n      desc: string","sourceCodeStart":336,"sourceCodeEnd":372,"githubUrl":"https://github.com/yikart/AiToEarn/blob/d3aa8bea5b146a8675607cf0144d891aad3e9683/project/aitoearn-backend/apps/aitoearn-server/src/core/channels/platforms/bilibili/bilibili.service.ts#L336-L372","documentation":"Bilibili's open-platform cover upload endpoint (POST /arcopen/fn/archive/cover/upload) completed at the HTTP level, but the response body contained no `data.url`. The service treats a cover upload without a returned URL as a platform-side media processing failure and throws ChannelPlatformMediaProcessingFailed, blaming the Bilibili platform (PlatformErrorCauseType.Platform) rather than the caller.","triggerScenarios":"Calling cover/uploadCover for a bilibili channel when the signed multipart POST succeeds but the JSON body is missing `data.data.url` — e.g. Bilibili returned an error code inside a 200 response, rejected the image silently, or changed the response shape.","commonSituations":"Cover image in an unsupported format/size (not jpg/png, oversized), expired or insufficiently scoped access_token causing an in-body error, Bilibili open API degradation, or an API version change that renames/moves the `url` field.","solutions":["Log the full response body of the cover upload call to see Bilibili's in-body error code/message (a 200 status can still carry an error payload).","Verify the cover file is a supported format (jpg/png) and within Bilibili's size limits before uploading.","Check the access token is valid and has archive-write scope; refresh it if expired and retry the upload.","Compare the actual response shape against this handler — if Bilibili moved the `url` field, update the extraction in bilibili.service.ts."],"exampleFix":"// before\nconst response = await this.platformHttp.post<BilibiliApiResponse<{ url: string }>>(`${this.openBaseUrl}/arcopen/fn/archive/cover/upload`, formData, { headers: this.buildSignedHeaders(accessToken, '', 'multipart/form-data') })\nif (!response.data.data?.url) {\n  throw new BilibiliPlatformException({ code: ResponseCode.ChannelPlatformMediaProcessingFailed, context: { endpoint: 'POST /arcopen/fn/archive/cover/upload' }, cause: { type: PlatformErrorCauseType.Platform } })\n}\n// after\nconst response = await this.platformHttp.post<BilibiliApiResponse<{ url: string }>>(`${this.openBaseUrl}/arcopen/fn/archive/cover/upload`, formData, { headers: this.buildSignedHeaders(accessToken, '', 'multipart/form-data') })\nthis.logger.warn({ body: response.data }, 'bilibili cover upload raw response') // surface in-body error code\nif (!response.data.data?.url) {\n  throw new BilibiliPlatformException({ code: ResponseCode.ChannelPlatformMediaProcessingFailed, context: { endpoint: 'POST /arcopen/fn/archive/cover/upload', body: response.data }, cause: { type: PlatformErrorCauseType.Platform } })\n}","handlingStrategy":"validation","validationCode":"// pre-flight checks before cover upload\nfunction validateCoverForBilibili(file: { mimetype: string; size: number }): string | null {\n  const allowed = ['image/jpeg', 'image/png']\n  if (!allowed.includes(file.mimetype)) return `unsupported format ${file.mimetype}; use jpg/png`\n  if (file.size > 5 * 1024 * 1024) return 'cover exceeds Bilibili size limit'\n  return null\n}","typeGuard":"function hasUploadedCoverUrl(res: BilibiliApiResponse<{ url: string }>): res is BilibiliApiResponse<{ url: string }> & { data: { data: { url: string } } } {\n  return typeof res?.data?.url === 'string' && res.data.url.length > 0\n}","tryCatchPattern":"try {\n  const coverUrl = await channels.cover(channelId, coverFile)\n} catch (e) {\n  if (e.code === 'ChannelPlatformMediaProcessingFailed') {\n    logger.warn('bilibili rejected cover upload; check image format/size and token, then retry')\n    // fall back to default cover or re-queue upload\n  } else throw e\n}","preventionTips":["Validate cover format and size client-side before upload.","Keep channel access tokens refreshed before publish flows.","Log raw platform responses to catch in-body errors hidden behind HTTP 200.","Pin/monitor the Bilibili open API version your parsing assumes."],"tags":["bilibili","media-upload","platform-api","response-validation"],"backgroundTag":"platform-media-processing-failed","analyzedSha":"d3aa8bea5b146a8675607cf0144d891aad3e9683","analyzedAt":"2026-08-31T14:19:24.185Z","schemaVersion":2},"datasetVersion":"2026-08-31T22:30:34.772Z"}