siyuan-note/siyuan · error

image MIME type is missing

Error message

image MIME type is missing

What it means

Raised by resolveAgentAttachment when an image attachment carries inline Data but an empty MIMEType. The image content protocol requires an explicit MIME type to build the multimodal content part; without it the data URL/content type cannot be constructed, so the attachment is rejected with this error instead of guessing the format.

Solutions

  1. Set attachment.MIMEType (e.g. "image/png", "image/jpeg") whenever constructing or loading an AgentAttachment with inline Data.
  2. If loading legacy records without MIMEType, detect the type from the image bytes (magic-number sniffing) before resolving.
  3. Validate attachments on ingest (reject empty MIMEType early) rather than at request-build time.
  4. Re-attach the image through the normal UI path so MIME metadata is populated.

Example fix

// before
attachment := AgentAttachment{Type: "image", Data: pngBytes}
// after
attachment := AgentAttachment{Type: "image", Data: pngBytes, MIMEType: "image/png"}
Defensive patterns

Strategy: validation

Validate before calling

function hasMime(a) { return a.type !== "image" || !a.data?.length || Boolean(a.mimeType) }

Type guard

func hasImageMIME(a AgentAttachment) bool {
    return a.Type != "image" || len(a.Data) == 0 || a.MIMEType != ""
}

Try / catch

data, mime, w, h, err := resolveAgentAttachment(att)
if err != nil {
    // sniff MIME from bytes (magic number) and retry once, else drop the attachment
}

Prevention

When it happens

Trigger: In attachments.go (~line 146): an AgentAttachment has len(attachment.Data) > 0 but attachment.MIMEType == "" — e.g. an attachment constructed programmatically or read from storage that lost its MIME metadata — and is then resolved by buildAttachmentMessage for inclusion in the model request.

Common situations: A plugin or script creates AgentAttachment objects manually and forgets to set MIMEType; an older saved attachment record predates the MIMEType field and unmarshals as empty; a data-import path copies Data but drops metadata.

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 siyuan-note/siyuan@9f775e8a12 (2026-09-19). Data as JSON: /api/errors/8d79b460ae0d1961. Report an issue: GitHub.

Appendix: source

Thrown at kernel/agent/attachments.go:146

	if imageCount == 0 {
		return openai.ChatCompletionMessage{}, false
	}
	if omitted {
		parts = append(parts, openai.ChatMessagePart{
			Type: openai.ChatMessagePartTypeText,
			Text: "One or more image attachments were omitted because they were unavailable or exceeded the request limit.",
		})
	}
	return openai.ChatCompletionMessage{
		Role:         openai.ChatMessageRoleUser,
		MultiContent: parts,
	}, true
}

func resolveAgentAttachment(attachment AgentAttachment) (data []byte, mimeType string, width, height int, err error) {
	if len(attachment.Data) > 0 {
		if attachment.MIMEType == "" {
			err = fmt.Errorf("image MIME type is missing")
			return
		}
		data = attachment.Data
		mimeType = attachment.MIMEType
		width = attachment.Width
		height = attachment.Height
		return
	}
	var prepared kernelModel.PreparedDocumentImage
	var prepareErr error
	if attachment.DocumentID == "" {
		prepared, prepareErr = kernelModel.PrepareAgentMessageImage(attachment.Path)
	} else {
		prepared, prepareErr = kernelModel.PrepareDocumentImage(attachment.DocumentID, attachment.Path)
	}
	if prepareErr != nil {
		err = prepareErr
		return

View on GitHub (pinned to 9f775e8a12)