siyuan-note/siyuan · error

generate image failed: %w

Error message

generate image failed: %w

What it means

Returned by GenerateImage when util.NewOpenAIImageAdapter(...).Generate(ctx, ...) returns an error. The error is wrapped with markImageExecutionUnknown, marking it as an execution-state-unknown failure: because the provider call has already started, the caller MUST NOT auto-retry (IsImageExecutionUnknown returns true). Underlying causes are network, HTTP, auth, rate-limit, or provider-side errors.

Source

Thrown at kernel/model/assets.go:437

		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,
	).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 251596fc0d)

Solutions

  1. Do NOT auto-retry: check IsImageExecutionUnknown first and surface the error to the user.
  2. Inspect the wrapped error for HTTP status: fix the API key (401), back off (429), or correct BaseURL/model name.
  3. Increase Conf.AI.ImageGeneration.RequestTimeout if the provider is slow but reliable.
  4. Verify the configured provider Protocol is openai and the model is image-capable (e.g. gpt-image-1, dall-e-3).

Example fix

// before
res, err := model.GenerateImage(ctx, req)
if err != nil { time.Sleep(time.Second); res, err = model.GenerateImage(ctx, req) } // WRONG

// after — never auto-retry execution-unknown failures
res, err := model.GenerateImage(ctx, req)
if err != nil {
    if model.IsImageExecutionUnknown(err) {
        return fmt.Errorf("generation may have started; not retrying: %w", err)
    }
    return err
}
Defensive patterns

Strategy: try-catch

Validate before calling

// Validate configuration before the call to catch the common pre-network causes.
if p, m := model.Conf.AI.GetImageGenerationModel(); p == nil || m == nil {
    return errors.New("image model not configured")
} else if p.Protocol != "" && p.Protocol != "openai" {
    return fmt.Errorf("provider protocol %q unsupported for images", p.Protocol)
}

Type guard

// Identify the no-retry sentinel so callers do not auto-retry.
func isImageExecUnknown(err error) bool { return model.IsImageExecutionUnknown(err) }

Try / catch

res, err := model.GenerateImage(ctx, req)
if err != nil {
    if model.IsImageExecutionUnknown(err) {
        // provider call began — do NOT auto-retry; surface to user
        return err
    }
    // pre-network validation error — safe to let the user correct and retry
    return err
}

Prevention

When it happens

Trigger: Provider API key invalid/expired (401), rate limited (429), bad base URL, request timeout exceeded (Conf.AI.ImageGeneration.RequestTimeout), provider returned a non-2xx body, DNS/TLS failure reaching BaseURL, or the model name is rejected by the provider.

Common situations: User pasted an OpenAI key without image-generation entitlement; BaseURL points to a gateway that doesn't proxy /images/generations; the network dropped mid-request; the configured model name doesn't support image output.

Related errors


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