{"record":{"id":"8d2dd53691eb840c","repo":"linshenkx/prompt-optimizer","slug":"label-index-1-must-provide-either-assetid","errorCode":null,"errorMessage":"${label} #${index + 1} must provide either assetId or b64.","messagePattern":"(.+?) #(.+?) must provide either assetId or b64\\.","errorType":"validation","errorClass":"EvaluationValidationError","httpStatus":null,"severity":"error","filePath":"packages/core/src/services/evaluation/service.ts","lineNumber":1679,"sourceCode":"\n  private hasMediaPayload(mediaItem: EvaluationMediaItem | null | undefined): boolean {\n    const assetId = mediaItem?.assetId?.trim() || '';\n    const b64 = mediaItem?.b64?.trim() || '';\n    return !!assetId || !!b64;\n  }\n\n  private validateMediaItems(mediaItems: EvaluationMediaItem[], label: string): void {\n    mediaItems.forEach((item, index) => {\n      const itemLabel = item?.label?.trim() || '';\n      const assetId = item?.assetId?.trim() || '';\n      const b64 = item?.b64?.trim() || '';\n\n      if (!itemLabel) {\n        throw new EvaluationValidationError(`${label} #${index + 1} label must not be empty.`);\n      }\n\n      if (!assetId && !b64) {\n        throw new EvaluationValidationError(\n          `${label} #${index + 1} must provide either assetId or b64.`\n        );\n      }\n\n      if (assetId && b64) {\n        throw new EvaluationValidationError(\n          `${label} #${index + 1} must not provide both assetId and b64.`\n        );\n      }\n    });\n  }\n\n  private validateContentBlock(\n    block: EvaluationContentBlock | undefined,\n    label: string\n  ): void {\n    if (!block) {\n      throw new EvaluationValidationError(`${label} must not be empty.`);","sourceCodeStart":1661,"sourceCodeEnd":1697,"githubUrl":"https://github.com/linshenkx/prompt-optimizer/blob/3e677b1d9f7e0493c142c175560531e7ae786dce/packages/core/src/services/evaluation/service.ts#L1661-L1697","documentation":"Each media item in an evaluation must reference its image by exactly one mechanism: either a stored assetId or inline base64 (b64). This error fires during validation when an item provides neither — both fields are absent or whitespace — so the service has no image payload to use.","triggerScenarios":"A media item in a content block's media array with neither assetId nor b64 (both missing, empty, or whitespace). The message includes the block label and 1-based item index.","commonSituations":"Building media items from user input where both fields were left blank; a form or importer that drops the image field when upload fails; refactoring code from b64 to assetId and accidentally removing both.","solutions":["Add either a valid assetId (from image storage) or a base64 data string to the offending media item","If the image is missing entirely, remove the media item rather than submitting an empty shell","Validate media arrays client-side before calling the evaluation API"],"exampleFix":"// before\nmedia: [{ label: 'prompt image' }]\n\n// after\nmedia: [{ label: 'prompt image', b64: base64String }]","handlingStrategy":"validation","validationCode":"function validateMediaSources(media: { assetId?: string; b64?: string }[]): void {\n  media.forEach((item, i) => {\n    const hasAsset = !!item?.assetId?.trim();\n    const hasB64 = !!item?.b64?.trim();\n    if (!hasAsset && !hasB64) throw new Error(`media[${i}] needs assetId or b64`);\n    if (hasAsset && hasB64) throw new Error(`media[${i}] must not set both assetId and b64`);\n  });\n}","typeGuard":"const hasImageSource = (m: { assetId?: string; b64?: string } | undefined): boolean =>\n  !!(m?.assetId?.trim() ^ m?.b64?.trim()); // exactly one set","tryCatchPattern":"try {\n  await evaluationService.create(request);\n} catch (err) {\n  if (err instanceof EvaluationValidationError && /either assetId or b64/.test(err.message)) {\n    fixMediaItemFromMessage(err.message); // attach assetId or b64 to the named item\n  } else throw err;\n}","preventionTips":["Model media items with a discriminated union: { kind: 'asset', assetId } | { kind: 'inline', b64 }","Never default both fields when constructing items","Validate media arrays client-side before submission"],"tags":["evaluation","validation","media","missing-field"],"backgroundTag":"schema-validation-failed","analyzedSha":"3e677b1d9f7e0493c142c175560531e7ae786dce","analyzedAt":"2026-08-27T21:29:16.709Z","schemaVersion":2},"datasetVersion":"2026-08-28T00:17:15.603Z"}