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
- Set Type to "text" (AIMessagePartTypeText) for text content
- Set Type to "file" (AIMessagePartTypeFile) for attachments
- 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
- Use the AIMessagePartTypeText/AIMessagePartTypeFile constants, never raw strings
- Translate third-party part types before constructing AIMessagePart
- Always set Type explicitly on hand-built parts
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
- text type requires non-empty text field
- text type cannot have file fields set
- file type cannot have text field set
- file type requires mimetype
- file type requires either data or url
AI-assisted analysis of wavetermdev/waveterm@a4447c1563 (2026-09-01).
Data as JSON: /api/errors/2ca7007c76182212.
Report an issue: GitHub.