wavetermdev/waveterm · error

type must be %q or %q, got %q

Error message

type must be %q or %q, got %q

What it means

AIMessagePart.Validate() only accepts Type "text" or "file" (AIMessagePartTypeText/AIMessagePartTypeFile); any other Type string falls through both branches and fails with this message showing the valid values and the received one.

Source

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

		if hasData && hasURL {
			return fmt.Errorf("file type cannot have both data and url set")
		}

		// If URL is set, validate it's https or data URL
		if hasURL {
			parsedURL, err := url.Parse(p.URL)
			if err != nil {
				return fmt.Errorf("invalid url: %w", err)
			}

			if parsedURL.Scheme != "https" && parsedURL.Scheme != "data" {
				return fmt.Errorf("url must be https or data URL, got %q", parsedURL.Scheme)
			}
		}
		return nil
	}

	return fmt.Errorf("type must be %q or %q, got %q", AIMessagePartTypeText, AIMessagePartTypeFile, p.Type)
}

// ---------------------
// AI SDK Streaming Protocol

// Type can be one of these consts...
// text-start, text-delta, text-end,
// reasoning-start, reasoning-delta, reasoning-end,
// source-url, source-document,
// file,
// data-*,
// tool-input-start, tool-input-delta, tool-input-available, tool-output-available,
// error, start-step, finish-step, finish
type UseChatStreamPart struct {
	Type string `json:"type"`

	// Text
	Text string `json:"text,omitempty"`

View on GitHub (pinned to a4447c1563)

Solutions

  1. Set Type to "text" (AIMessagePartTypeText) for text content
  2. Set Type to "file" (AIMessagePartTypeFile) for attachments
  3. Translate foreign part types (e.g. "image_url" -> "file" with MimeType) before validating

Example fix

// before
part := uctypes.AIMessagePart{Type: "image", URL: "https://example.com/a.png", MimeType: "image/png"}
// after
part := uctypes.AIMessagePart{Type: uctypes.AIMessagePartTypeFile, URL: "https://example.com/a.png", MimeType: "image/png"}
Defensive patterns

Strategy: type-guard

Validate before calling

func knownPartType(t string) bool {
	return t == uctypes.AIMessagePartTypeText || t == uctypes.AIMessagePartTypeFile
}

Type guard

func classifyPart(p uctypes.AIMessagePart) (string, bool) {
	switch p.Type {
	case uctypes.AIMessagePartTypeText, uctypes.AIMessagePartTypeFile:
		return p.Type, true
	default:
		return "", false
	}
}

Prevention

When it happens

Trigger: AIMessagePart{Type:"image"} or {Type:""} (empty type) passed to Validate(); client JSON using a different part vocabulary (e.g. "image_url", "image/png") than the two supported types.

Common situations: Porting from other AI SDK part formats (OpenAI content parts, AI SDK UI messages) without translating the type; typo like "txt" or "files"; forgetting to set Type at all on a manually built part.

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/2ca7007c76182212. Report an issue: GitHub.