wavetermdev/waveterm · error

part %d: text type requires non-empty text field

Error message

part %d: text type requires non-empty text field

What it means

When converting message parts, a text-type part with an empty Text field would produce a useless empty input_text content block, so the converter rejects it with this error naming the offending part index. OpenAI requires text content to be non-empty.

Source

Thrown at pkg/aiusechat/openai/openai-convertmessage.go:413

}

// ConvertAIMessageToOpenAIChatMessage converts an AIMessage to OpenAIChatMessage
// These messages are ALWAYS role "user"
// Handles text parts, images, PDFs, and text/plain files
func ConvertAIMessageToOpenAIChatMessage(aiMsg uctypes.AIMessage) (*OpenAIChatMessage, error) {
	if err := aiMsg.Validate(); err != nil {
		return nil, fmt.Errorf("invalid AIMessage: %w", err)
	}

	var contentBlocks []OpenAIMessageContent
	imageCount := 0
	imageFailCount := 0

	for i, part := range aiMsg.Parts {
		switch part.Type {
		case uctypes.AIMessagePartTypeText:
			if part.Text == "" {
				return nil, fmt.Errorf("part %d: text type requires non-empty text field", i)
			}
			contentBlocks = append(contentBlocks, OpenAIMessageContent{
				Type: "input_text",
				Text: part.Text,
			})

		case uctypes.AIMessagePartTypeFile:
			if strings.HasPrefix(part.MimeType, "image/") {
				imageCount++
			}
			block, err := convertFileAIMessagePart(part)
			if err != nil {
				if strings.HasPrefix(part.MimeType, "image/") {
					imageFailCount++
				}
				log.Printf("openai: %v", err)
				continue
			}

View on GitHub (pinned to a4447c1563)

Solutions

  1. Skip or drop empty text parts before calling the converter
  2. Replace empty text with placeholder content if the part is required
  3. Add a pre-call check on aiMsg.Parts that removes parts where Type==text && Text==""

Example fix

// before
parts := []uctypes.AIMessagePart{{Type: uctypes.AIMessagePartTypeText, Text: ""}}
// after
parts := []uctypes.AIMessagePart{}
for _, p := range parts {
    if p.Type == uctypes.AIMessagePartTypeText && p.Text == "" { continue }
    parts = append(parts, p)
}
Defensive patterns

Strategy: validation

Validate before calling

for i, p := range aiMsg.Parts {
    if p.Type == uctypes.AIMessagePartTypeText && p.Text == "" {
        return fmt.Errorf("part %d has empty text", i)
    }
}

Prevention

When it happens

Trigger: An AIMessage passed to ConvertAIMessageToOpenAIChatMessage contains a part with Type == uctypes.AIMessagePartTypeText and part.Text == "".

Common situations: Building user messages from form input without checking for empty strings; trimming that reduces text to ""; appending placeholder text parts meant to be filled in later.

Understand the failure class

Background: "must not be empty", "cannot be empty" — required-field validation errors across open-source libraries — this error's family across 41 libraries.

Related errors


AI-assisted analysis of wavetermdev/waveterm@a4447c1563 (2026-09-01). Data as JSON: /api/errors/7ce950ac6919c29a. Report an issue: GitHub.