wavetermdev/waveterm · error

messageid must be set

Error message

messageid must be set

What it means

AIMessage.Validate enforces that every AI message carries a non-empty MessageId, which is used for correlation, streaming, and deduplication in the UI message protocol. A message constructed or deserialized without an ID fails validation before it is accepted into the conversation pipeline.

Source

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

	URL        string `json:"url,omitempty"`
	Size       int    `json:"size,omitempty"`
	PreviewUrl string `json:"previewurl,omitempty"` // 128x128 webp data url for images
}

type AIToolResult struct {
	ToolName  string `json:"toolname"`
	ToolUseID string `json:"tooluseid"`
	ErrorText string `json:"errortext,omitempty"`
	Text      string `json:"text,omitempty"`
}

func (m *AIMessage) GetMessageId() string {
	return m.MessageId
}

func (m *AIMessage) Validate() error {
	if m.MessageId == "" {
		return fmt.Errorf("messageid must be set")
	}

	if len(m.Parts) == 0 {
		return fmt.Errorf("parts must not be empty")
	}

	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 == "" {

View on GitHub (pinned to a4447c1563)

Solutions

  1. Set MessageId before calling Validate, using a unique id (uuid or existing conversation-scoped id)
  2. Check the JSON/serialization source actually includes the message id field
  3. In test code, use a helper/factory that always assigns MessageId
  4. Add validation at deserialization boundaries so bad data is rejected early

Example fix

// before
msg := &uctypes.AIMessage{Parts: parts}
err := msg.Validate() // "messageid must be set"
// after
msg := &uctypes.AIMessage{MessageId: uuid.NewString(), Parts: parts}
err := msg.Validate()
Defensive patterns

Strategy: validation

Validate before calling

if msg == nil || msg.MessageId == "" {
    return fmt.Errorf("AIMessage requires a non-empty MessageId")
}

Type guard

func isValidAIMessage(m *uctypes.AIMessage) bool {
    return m != nil && m.MessageId != ""
}

Try / catch

if err := msg.Validate(); err != nil {
    if strings.Contains(err.Error(), "messageid must be set") {
        msg.MessageId = uuid.NewString()
        err = msg.Validate()
    }
}

Prevention

When it happens

Trigger: Calling Validate() on an AIMessage whose MessageId field is "" — e.g. after unmarshaling JSON lacking the messageid, or constructing AIMessage{} manually.

Common situations: Deserializing messages from an external source that omits the id; hand-constructed test messages; migrating from an older wire format without message ids.

Understand the failure class

Background: "missing required argument" and "the following required arguments were not provided": what required-argument errors mean and how to fix them — this error's family across 20 libraries.

Related errors


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