{"record":{"id":"e3554f7b9e14e874","repo":"yikart/AiToEarn","slug":"invalid-data-uri","errorCode":null,"errorMessage":"Invalid data URI","messagePattern":"Invalid data URI","errorType":"exception","errorClass":"BadRequestException","httpStatus":400,"severity":"warning","filePath":"project/aitoearn-backend/apps/aitoearn-ai/src/core/ai/image/image.service.ts","lineNumber":63,"sourceCode":"\n    return modelConfig?.runtimeModel ?? model\n  }\n\n  private getImageModelRetry(model: string, kind: 'generation' | 'edit'): number {\n    const modelConfig = kind === 'generation'\n      ? this.modelsConfigService.config.image.generation.find(item => item.name === model)\n      : this.modelsConfigService.config.image.edit.find(item => item.name === model)\n\n    return modelConfig?.retry ?? 0\n  }\n\n  /**\n   * 将 data uri 转换为 Uploadable\n   */\n  private getUploadableByDataUri(dataUri: string, filename = 'image'): Uploadable {\n    const file = parseDataUri(dataUri)\n    if (file == null) {\n      throw new BadRequestException('Invalid data URI')\n    }\n    const ext = getExtByMimeType(file.mimeType.essence as ImageType)\n\n    return new File([file.body as Uint8Array<ArrayBuffer>], `${filename}.${ext}`, { type: file.mimeType.essence })\n  }\n\n  /**\n   * 将 URL 转换为 Uploadable\n   */\n  private async getUploadableByUrl(url: string): Promise<Uploadable> {\n    return await fetch(url)\n  }\n\n  /**\n   * 将 URL 或 Data URI 转换为 Uploadable\n   */\n  private async getUploadableByUrlOrDataUri(urlOrDataUri: string, filename = 'image'): Promise<Uploadable> {\n    if (/^https?:\\/\\//.test(urlOrDataUri)) {","sourceCodeStart":45,"sourceCodeEnd":81,"githubUrl":"https://github.com/yikart/AiToEarn/blob/d3aa8bea5b146a8675607cf0144d891aad3e9683/project/aitoearn-backend/apps/aitoearn-ai/src/core/ai/image/image.service.ts#L45-L81","documentation":"getUploadableByDataUri converts a data URI string into a Uploadable file object for the AI SDK. It uses the WHATWG data-urls parser, which strictly requires the format `data:[<mediatype>][;base64],<data>` with a supported MIME type. If parseDataUri returns null the URI is not a valid data URL (or uses an unsupported scheme/mediatype) and this BadRequestException is thrown.","triggerScenarios":"Caller passes getUploadableByUrlOrDataUri a string that is not a well-formed data URI: missing the `data:` prefix or comma separator, no base64/plain marker, URL-encoded or otherwise mangled base64 payload, an exotic mediatype the parser rejects, or the caller mislabels a plain base64 string / http URL as a data URI.","commonSituations":"Clients sending base64 image payloads without the data URI envelope; frontend code that strips or corrupts the prefix; a field containing an http(s) URL routed into the data-URI branch; copying a data URI truncated by logs or message-size limits.","solutions":["Verify the string starts with `data:` and contains a comma separating the mediatype from the payload","Ensure binary payloads use `;base64` and that the base64 is valid (no whitespace/newlines/url-encoding)","Check the MIME type is an image type the service accepts (it casts to ImageType for getExtByMimeType)","If the source is an http URL, do not pass it here — use the URL branch of getUploadableByUrlOrDataUri instead","Log a prefix of the failing string to detect truncation by upstream clients"],"exampleFix":"// before\nconst uploadable = imageService.getUploadableByUrlOrDataUri(rawBase64)\n// after\nconst dataUri = rawBase64.startsWith('data:') ? rawBase64 : `data:image/png;base64,${rawBase64}`\nconst uploadable = imageService.getUploadableByUrlOrDataUri(dataUri)","handlingStrategy":"validation","validationCode":"function isImageDataUri(s: string): boolean {\n  return /^data:image\\/[a-z0-9.+-]+(;base64)?,/i.test(s)\n}\n// call before: if (!isImageDataUri(input)) throw new BadRequestException('expected a data:image/... URI')","typeGuard":"function isDataUri(v: unknown): v is `data:${string}` {\n  return typeof v === 'string' && v.startsWith('data:') && v.includes(',')\n}","tryCatchPattern":"try {\n  const uploadable = getUploadableByUrlOrDataUri(input)\n} catch (e) {\n  if (e instanceof BadRequestException && e.message === 'Invalid data URI') {\n    throw new BadRequestException('Image must be a valid data:image/...;base64,... URI or an http(s) URL')\n  }\n  throw e\n}","preventionTips":["Always send base64 payloads wrapped as `data:image/png;base64,...`, never raw base64","Never pass http(s) URLs into the data-URI branch","Validate with a regex prefix check before calling the API","Watch for clients truncating long data URIs in logs or payloads"],"tags":["validation","input","data-uri"],"backgroundTag":"invalid-data-uri","analyzedSha":"d3aa8bea5b146a8675607cf0144d891aad3e9683","analyzedAt":"2026-08-31T14:19:24.185Z","schemaVersion":2},"datasetVersion":"2026-08-31T19:17:28.585Z"}