{"record":{"id":"b0ab12b8d2f9adf4","repo":"yikart/AiToEarn","slug":"text-prompt-is-required","errorCode":null,"errorMessage":"text prompt is required","messagePattern":"text prompt is required","errorType":"validation","errorClass":"BadRequestException","httpStatus":400,"severity":"error","filePath":"project/aitoearn-backend/apps/aitoearn-ai/src/core/ai/video/volcengine/volcengine.service.ts","lineNumber":214,"sourceCode":"      const parsed = parseModelTextCommand(item.text)\n      if (!prompt && parsed.prompt) {\n        prompt = parsed.prompt\n      }\n      inlineResolution = inlineResolution ?? parsed.params.resolution\n      inlineRatio = inlineRatio ?? parsed.params.ratio\n      inlineDuration = inlineDuration ?? parsed.params.duration\n      inlineSeed = inlineSeed ?? parsed.params.seed\n      inlineWatermark = inlineWatermark ?? parsed.params.watermark\n\n      return {\n        ...item,\n        text: parsed.prompt,\n      }\n    })\n\n    this.validateContent(normalizedContent)\n    if (!prompt.trim()) {\n      throw new BadRequestException('text prompt is required')\n    }\n\n    const aiLogRequest = {\n      model: request.model,\n      content: normalizedContent,\n      return_last_frame: request.return_last_frame,\n      resolution: request.resolution ?? inlineResolution,\n      ratio: request.ratio ?? inlineRatio,\n      duration: request.duration ?? inlineDuration,\n      seed: request.seed ?? inlineSeed,\n      watermark: request.watermark ?? inlineWatermark,\n      tools: request.tools,\n    }\n\n    const requestBody: CreateVideoGenerationTaskRequest = {\n      ...aiLogRequest,\n      callback_url: config.ai.volcengine?.callbackUrl,\n      safety_identifier: this.buildSafetyIdentifier(request.userId, request.userType),","sourceCodeStart":196,"sourceCodeEnd":232,"githubUrl":"https://github.com/yikart/AiToEarn/blob/d3aa8bea5b146a8675607cf0144d891aad3e9683/project/aitoearn-backend/apps/aitoearn-ai/src/core/ai/video/volcengine/volcengine.service.ts#L196-L232","documentation":"After validating content, normalizeRequest extracts a plain-text prompt from text-type content items and throws this BadRequestException if the resulting prompt string is empty/whitespace. A non-empty text prompt is mandatory for Volcengine video generation regardless of media inputs.","triggerScenarios":"Calling generation with content containing only media URLs (images/videos/audio) and no text item, or a text item with an empty/whitespace string.","commonSituations":"UI where the user uploads an image but leaves the description blank; clients assuming image-only (text-free) generation is supported; prompt extracted from the wrong field.","solutions":["Include a text content item with a non-empty prompt","Trim and check the prompt client-side before sending","If the flow is image-driven, still supply a short descriptive prompt"],"exampleFix":"// before\ncontent: [{ type:'image_url', role:'first_frame', url: img }]\n// after\ncontent: [{ type:'text', text: 'cinematic slow motion' }, { type:'image_url', role:'first_frame', url: img }]","handlingStrategy":"validation","validationCode":"const prompt = content.filter(c => c.type === 'text').map(c => c.text).join(' ').trim(); if (!prompt) throw new Error('text prompt is required')","typeGuard":"const hasPrompt = (c: Content[]): c is [Extract<Content, {type: typeof ContentType.Text}>, ...Content[]] => c.some(i => i.type === ContentType.Text && i.text.trim().length > 0)","tryCatchPattern":"try { await generate(req) } catch (e) { if (e instanceof BadRequestException && e.message === 'text prompt is required') { /* surface a required-prompt error to the user */ } else throw e }","preventionTips":["Make the prompt field mandatory in generation UIs","Trim prompt input and reject whitespace-only values","Remember: even image-driven generation needs a text prompt"],"tags":["validation","bad-request","prompt"],"backgroundTag":"empty-required-field","analyzedSha":"d3aa8bea5b146a8675607cf0144d891aad3e9683","analyzedAt":"2026-08-31T14:19:24.185Z","schemaVersion":2},"datasetVersion":"2026-08-31T19:17:28.585Z"}