siyuan-note/siyuan · error

generate image failed

Error message

generate image failed: %w

What it means

GenerateImage delegates actual image synthesis to util.NewOpenAIImageAdapter(...).Generate. Any error returned by the provider call (network failure, HTTP error, auth rejection, malformed response) is wrapped as "generate image failed: %w" and passed through markImageExecutionUnknown, since the request may or may not have consumed provider quota.

Solutions

  1. Inspect the wrapped cause (%w) for the HTTP status / provider error message and fix accordingly (key, quota, model)
  2. Verify Settings - AI provider API key and base URL, ensuring the endpoint implements the image generation API
  3. Check network/proxy connectivity to the provider host and retry after backoff on 429/5xx
  4. Increase Conf.AI.ImageGeneration.RequestTimeout if timeouts are the cause

Example fix

// before
provider.BaseURL = "https://relay.example.com/v1" // no /images endpoint
// after
provider.BaseURL = "https://api.openai.com/v1" // OpenAI-compatible image API
Defensive patterns

Strategy: retry

Validate before calling

provider, m := conf.Conf.AI.GetImageGenerationModel()
if provider == nil || provider.APIKey == "" || m == nil {
    return errors.New("image provider/key/model not configured")
}

Try / catch

var apiErr *util.APIError // or inspect wrapped error
res, err := model.GenerateImage(ctx, req)
if err != nil {
    if strings.Contains(err.Error(), "429") {
        time.Sleep(backoff); return model.GenerateImage(ctx, req) // retry rate limits
    }
    return fmt.Errorf("image provider failed: %w", err)
}

Prevention

When it happens

Trigger: The OpenAI-compatible image endpoint returns a non-2xx response (401 invalid API key, 402/429 quota, 5xx), the base URL is wrong, the network is unreachable, the context deadline (RequestTimeout) expires, or the response body cannot be parsed as an image result.

Common situations: Expired or revoked API key; third-party relay base URL that does not implement the images API; rate limiting after bursts of generations; firewall/proxy blocking the provider host; model name not enabled for image output on the account.

Related errors


AI-assisted analysis of siyuan-note/siyuan@9f775e8a12 (2026-09-19). Data as JSON: /api/errors/14a0990e7943174b. Report an issue: GitHub.

Appendix: source

Thrown at kernel/model/assets.go:545

		return GenerateImageResult{}, err
	}
	prompt := strings.TrimSpace(request.Prompt)
	if prompt == "" {
		return GenerateImageResult{}, errors.New("prompt is required for image generation")
	}
	size := multimodalValueOrDefault(request.Size, Conf.AI.ImageGeneration.Size)
	quality := multimodalValueOrDefault(request.Quality, Conf.AI.ImageGeneration.Quality)
	outputFormat := strings.ToLower(multimodalValueOrDefault(request.OutputFormat, Conf.AI.ImageGeneration.OutputFormat))
	if outputFormat != "png" && outputFormat != "jpeg" && outputFormat != "webp" {
		return GenerateImageResult{}, errors.New("unsupported image output format")
	}
	generated, err := util.NewOpenAIImageAdapter(
		provider.APIKey, provider.BaseURL, generationModel.Name, Conf.AI.ImageGeneration.RequestTimeout, ResolveAIProviderHeaders(provider),
	).Generate(ctx, util.GenerateImageRequest{
		Prompt: prompt, Size: size, Quality: quality, OutputFormat: outputFormat,
	})
	if err != nil {
		return GenerateImageResult{}, markImageExecutionUnknown(fmt.Errorf("generate image failed: %w", err))
	}
	if ctx.Err() != nil {
		return GenerateImageResult{}, markImageExecutionUnknown(errors.New("image generation was cancelled"))
	}
	return GenerateImageResult{
		Data: generated.Data, MIMEType: generated.MIMEType, Extension: generated.Extension, RevisedPrompt: generated.RevisedPrompt,
	}, nil
}

// GenerateDocumentImage 使用通用图片生成能力创建文档资源。
func GenerateDocumentImage(ctx context.Context, request GenerateDocumentImageRequest) (GenerateDocumentImageResult, error) {
	bt, err := resolveMultimodalDocument(request.DocumentID)
	if err != nil {
		return GenerateDocumentImageResult{}, err
	}
	generated, err := GenerateImage(ctx, GenerateImageRequest{
		Prompt: request.Prompt, Size: request.Size, Quality: request.Quality, OutputFormat: request.OutputFormat,
	})

View on GitHub (pinned to 9f775e8a12)