siyuan-note/siyuan · error

generated image is empty

Error message

generated image is empty

What it means

ValidateGeneratedImage in kernel/util/openai.go throws this when validating a byte slice returned by an image-generation API and the slice has length 0. It means the adapter produced no image data at all despite (presumably) reporting success.

Solutions

  1. Check the raw API response to confirm whether the model actually returned image data
  2. Verify the b64_json / URL field is present and non-empty in the response JSON
  3. Retry the generation request — transient upstream failures can yield empty payloads
  4. Upgrade SiYuan in case the adapter's response parsing was fixed for a changed API format

Example fix

// before: decoding whatever the API returned
imgData, _ := base64.StdEncoding.DecodeString(resp.Data[0].B64JSON)
if err := ValidateGeneratedImage(imgData); err != nil { ... }
// after: guard the empty payload at the source
if resp.Data[0].B64JSON == "" {
    return errors.New("model returned no image data")
}
imgData, _ := base64.StdEncoding.DecodeString(resp.Data[0].B64JSON)
if err := ValidateGeneratedImage(imgData); err != nil { ... }
Defensive patterns

Strategy: validation

Validate before calling

if b64 == "" { return errors.New("model returned no image data") }
imgData, err := base64.StdEncoding.DecodeString(b64)
if err != nil { return err }
if len(imgData) == 0 { return errors.New("decoded image payload is empty") }

Try / catch

mime, ext, err := util.ValidateGeneratedImage(data)
if err != nil && err.Error() == "generated image is empty" {
    // treat as transient upstream failure; retry the generation once
    return retryGeneration()
}

Prevention

When it happens

Trigger: An AI image-generation response is parsed into an empty byte slice — e.g. an empty b64 field, a missing image payload, or a download of the generated image URL that returned zero bytes.

Common situations: Upstream model API changes its response shape; empty b64_json field in the JSON; a signed URL that returned an empty body; base64 decoding of an empty string succeeds silently.

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

Appendix: source

Thrown at kernel/util/openai.go:838

	if err = jpeg.Encode(&output, decoded, &jpeg.Options{Quality: 92}); err != nil {
		return PreparedImage{}, errors.New("encode image failed: " + err.Error())
	}
	if maxBytes > 0 && output.Len() > maxBytes {
		return PreparedImage{}, fmt.Errorf("prepared image exceeds size limit: %d bytes", maxBytes)
	}
	return PreparedImage{
		Data:       output.Bytes(),
		MIMEType:   "image/jpeg",
		Width:      bounds.Dx(),
		Height:     bounds.Dy(),
		SourceSize: len(data),
	}, nil
}

// 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 {

View on GitHub (pinned to 9f775e8a12)