siyuan-note/siyuan · warning
image generation was cancelled
Error message
image generation was cancelled
What it means
Returned by GenerateImage when Generate returned no error but ctx.Err() is non-nil afterwards — the caller's context was cancelled or expired while the provider was processing. Because the request already reached the provider (and may still produce a charge/result), it is wrapped with markImageExecutionUnknown and must not be retried automatically.
Source
Thrown at kernel/model/assets.go:440
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,
})
if err != nil {
return GenerateDocumentImageResult{}, err
}View on GitHub (pinned to 251596fc0d)
Solutions
- Treat as terminal for this attempt: do not retry on the same context (it is already cancelled).
- If the user wants to try again, start a fresh context with a longer timeout and confirm with the user first.
- Raise Conf.AI.ImageGeneration.RequestTimeout if cancellations are timeout-driven, not user-driven.
Example fix
// before
res, err := model.GenerateImage(ctx, req)
if err != nil { res, err = model.GenerateImage(ctx, req) } // ctx already dead — loops forever
// after
res, err := model.GenerateImage(ctx, req)
if err != nil && model.IsImageExecutionUnknown(err) {
if ctx.Err() != nil {
return fmt.Errorf("cancelled by caller (%w); not retrying", ctx.Err())
}
return err
} Defensive patterns
Strategy: try-catch
Type guard
func isCancelledGeneration(err error) bool {
return model.IsImageExecutionUnknown(err)
} Try / catch
res, err := model.GenerateImage(ctx, req)
if err != nil && model.IsImageExecutionUnknown(err) && ctx.Err() != nil {
// caller's context died — do not retry on the same (dead) context
return fmt.Errorf("generation cancelled: %w", ctx.Err())
} Prevention
- Use a context with a timeout sized to real provider latency to avoid mid-call expiry.
- On user cancel, treat the result as terminal — confirm before any retry.
- Distinguish timeout-driven cancellation from user-driven cancellation in user messaging.
When it happens
Trigger: The user cancelled the operation; a parent context deadline (RequestTimeout or higher-level timeout) fired mid-call; the kernel is shutting down and cancelled the ctx.
Common situations: User clicked cancel on a long generation; the client closed the WebSocket/HTTP connection so the kernel cancelled the ctx; an aggressive outer timeout wraps the call.
Related errors
- generate image failed: %w
- save generated image failed: %w
- no AI provider configured
- no AI editing config
- AI configuration is unavailable
AI-assisted analysis of siyuan-note/siyuan@251596fc0d (2026-08-12).
Data as JSON: /api/errors/0b8e09338acdbd74.
Report an issue: GitHub.