wavetermdev/waveterm · error

text type cannot have file fields set

Error message

text type cannot have file fields set

What it means

AIMessagePart.Validate() rejects a "text" part that also sets file-only fields (FileName, MimeType, Data, URL). Part types are mutually exclusive: a text part is pure text and must not smuggle attachment fields.

Source

Thrown at pkg/aiusechat/uctypes/uctypes.go:404

	}

	for i, part := range m.Parts {
		if err := part.Validate(); err != nil {
			return fmt.Errorf("part %d: %w", i, err)
		}
	}

	return nil
}

func (p *AIMessagePart) Validate() error {
	if p.Type == AIMessagePartTypeText {
		if p.Text == "" {
			return fmt.Errorf("text type requires non-empty text field")
		}
		// Check that no file fields are set
		if p.FileName != "" || p.MimeType != "" || len(p.Data) > 0 || p.URL != "" {
			return fmt.Errorf("text type cannot have file fields set")
		}
		return nil
	}

	if p.Type == AIMessagePartTypeFile {
		if p.Text != "" {
			return fmt.Errorf("file type cannot have text field set")
		}

		if p.MimeType == "" {
			return fmt.Errorf("file type requires mimetype")
		}

		// Either data or url (not both) must be set
		hasData := len(p.Data) > 0
		hasURL := p.URL != ""

		if !hasData && !hasURL {

View on GitHub (pinned to a4447c1563)

Solutions

  1. Remove the file fields (FileName, MimeType, Data, URL) from the text part
  2. Split into two parts: a text part and a separate file part
  3. Reset the part struct (zero value) before setting the text fields

Example fix

// before
part := uctypes.AIMessagePart{Type: "text", Text: "see attachment", FileName: "a.png", MimeType: "image/png"}
// after
parts := []uctypes.AIMessagePart{
	{Type: "text", Text: "see attachment"},
	{Type: "file", FileName: "a.png", MimeType: "image/png", Data: data},
}
Defensive patterns

Strategy: validation

Validate before calling

func validPureTextPart(p uctypes.AIMessagePart) bool {
	return p.Type == uctypes.AIMessagePartTypeText && p.Text != "" &&
		p.FileName == "" && p.MimeType == "" && len(p.Data) == 0 && p.URL == ""
}

Type guard

func asPureTextPart(p uctypes.AIMessagePart) (string, bool) {
	if p.Type == uctypes.AIMessagePartTypeText && p.Text != "" &&
		p.FileName == "" && p.MimeType == "" && len(p.Data) == 0 && p.URL == "" {
		return p.Text, true
	}
	return "", false
}

Prevention

When it happens

Trigger: Constructing AIMessagePart{Type:"text", Text:"hi", MimeType:"image/png"} (or FileName/Data/URL set) and calling Validate(). Also happens when reusing/re-purposing a file part struct and only changing Type to "text" without clearing the file fields.

Common situations: Copied struct literals reused for a different part type; unmarshaling loose JSON that includes both text and file keys; refactoring code that merged text and attachment handling.

Understand the failure class

Background: Schema validation failed / invalid input schema: payload rejected because its shape doesn't match the expected schema — this error's family across 28 libraries.

Related errors


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