siyuan-note/siyuan · error

unsupported generated image type: %s

Error message

unsupported generated image type: %s

What it means

Thrown by ValidateGeneratedImage (kernel/util/openai.go:712) when mimetype.Detect reports a MIME type that is not image/png, image/jpeg, or image/webp. SiYuan only persists those three formats for generated images; anything else (GIF, AVIF, HEIC, BMP, or non-image content) is rejected before dimension validation.

Source

Thrown at kernel/util/openai.go:712

// ValidateGeneratedImage 校验生成图片的格式、尺寸和体积。
func ValidateGeneratedImage(data []byte) (mimeType, extension string, err error) {
	if len(data) == 0 {
		return "", "", errors.New("generated image is empty")
	}
	if len(data) > maxGeneratedImageBytes {
		return "", "", errors.New("generated image exceeds size limit")
	}
	mimeType = mimetype.Detect(data).String()
	switch mimeType {
	case "image/png":
		extension = ".png"
	case "image/jpeg":
		extension = ".jpg"
	case "image/webp":
		extension = ".webp"
	default:
		return "", "", fmt.Errorf("unsupported generated image type: %s", mimeType)
	}
	config, _, decodeErr := image.DecodeConfig(bytes.NewReader(data))
	if decodeErr != nil || config.Width < 1 || config.Height < 1 || config.Width > 16384 || config.Height > 16384 ||
		int64(config.Width)*int64(config.Height) > maxGeneratedImagePixels {
		return "", "", errors.New("generated image is invalid")
	}
	return mimeType, extension, nil
}

func NewOpenAIImageAdapter(apiKey, apiBaseURL, model string, timeout int) *OpenAIImageAdapter {
	if timeout < 1 {
		timeout = 30
	}
	return &OpenAIImageAdapter{
		client:  NewOpenAIClientWithModel(apiKey, apiBaseURL, model),
		model:   model,
		timeout: time.Duration(timeout) * time.Second,
	}

View on GitHub (pinned to 251596fc0d)

Solutions

  1. Log the detected mimeType string to identify what the provider actually returned.
  2. If you control the request, force OutputFormat/ResponseFormat to png/jpeg/webp on the GenerateImageRequest.
  3. If extending support is intended, add the new MIME case to the switch and a matching decoder registration for image.DecodeConfig.
  4. If the body is an error page (HTML/JSON), the upstream call failed silently — check API key, quota, and provider status.

Example fix

// before
mimeType = mimetype.Detect(data).String()
switch mimeType {
case "image/png":  extension = ".png"
case "image/jpeg": extension = ".jpg"
case "image/webp": extension = ".webp"
default:
    return "", "", fmt.Errorf("unsupported generated image type: %s", mimeType)
}

// after (extend support + clearer rejection)
mimeType = mimetype.Detect(data).String()
switch mimeType {
case "image/png":  extension = ".png"
case "image/jpeg": extension = ".jpg"
case "image/webp": extension = ".webp"
case "image/avif": extension = ".avif"
default:
    return "", "", fmt.Errorf("unsupported generated image type %q (first bytes: % x)", mimeType, data[:min(16, len(data))])
}
Defensive patterns

Strategy: validation

Validate before calling

// Detect the MIME type the same way ValidateGeneratedImage does, then allow-list
allowed := map[string]bool{"image/png": true, "image/jpeg": true, "image/webp": true}
mt := mimetype.Detect(data).String()
if !allowed[mt] {
    return fmt.Errorf("pre-check: provider returned %s, not png/jpeg/webp", mt)
}

Try / catch

mimeType, ext, err := ValidateGeneratedImage(data)
if err != nil && strings.HasPrefix(err.Error(), "unsupported generated image type") {
    // provider returned a non-whitelisted format; either extend the switch or fix upstream
    logging.LogErrorf("unexpected image MIME: %s", err)
}
if err != nil { return err }

Prevention

When it happens

Trigger: Provider returns bytes whose magic bytes sniff as GIF/BMP/TIFF/AVIF/HEIC; or returns an HTML/JSON error body that mimetype classifies as text/html or application/json; or returns a corrupted buffer whose leading bytes match a non-image signature.

Common situations: Model misconfigured to emit unsupported format; API key invalid and provider returned an HTML error page captured as the 'image'; partial download whose first bytes coincidentally sniff as a non-image type; new model outputting AVIF before SiYuan whitelisted it.

Related errors


AI-assisted analysis of siyuan-note/siyuan@251596fc0d (2026-08-12). Data as JSON: /api/errors/996640cad064227b. Report an issue: GitHub.