siyuan-note/siyuan · warning
image generation was cancelled
Error message
image generation was cancelled
What it means
After the adapter call succeeds, GenerateImage checks ctx.Err(); if the caller's context was cancelled or its deadline expired during generation, the result is discarded and "image generation was cancelled" is returned (also marked as execution-unknown). This prevents committing images whose generation the caller no longer wants.
Solutions
- Retry with a fresh, non-cancelled context if the generation is still wanted
- Use context.WithTimeout with a generous deadline (at least Conf.AI.ImageGeneration.RequestTimeout plus margin)
- If cancellation is intentional (user abort), treat this error as expected and skip reporting it to the user
Example fix
// before ctx, cancel := context.WithTimeout(ctx, 10*time.Second) defer cancel() // after ctx, cancel := context.WithTimeout(context.Background(), 2*time.Minute) defer cancel() result, err := model.GenerateImage(ctx, req)
Defensive patterns
Strategy: try-catch
Validate before calling
if ctx.Err() != nil {
return errors.New("context already cancelled before generation started")
} Try / catch
res, err := model.GenerateImage(ctx, req)
if err != nil && err.Error() == "image generation was cancelled" {
if errors.Is(ctx.Err(), context.DeadlineExceeded) {
// retry with a longer deadline
}
// user-initiated cancellation: log and return quietly
} Prevention
- Use a timeout comfortably larger than Conf.AI.ImageGeneration.RequestTimeout
- Avoid tying the generation context to short-lived UI lifecycles
- Treat cancellation errors as user intent, not failures, in logs
When it happens
Trigger: The caller's context.Context is cancelled (user aborted, request shut down) or its deadline passes while the provider request is in flight or just as it completes.
Common situations: Closing the AI chat panel mid-generation; an HTTP client disconnecting cancels the gin request context; a short parent deadline (e.g. 30s) expiring before a slow provider finishes.
Understand the failure class
Background: Request timed out: what client-side request timeouts mean across libraries (Request timed out, TIMED_OUT, APITimeoutError) — this error's family across 39 libraries.
Related errors
- capability execution was cancelled before it started
- tool execution was cancelled before it started
- AI configuration is unavailable
- AI editor action must not be empty
- AI editor action not found
AI-assisted analysis of siyuan-note/siyuan@9f775e8a12 (2026-09-19).
Data as JSON: /api/errors/0b8e09338acdbd74.
Report an issue: GitHub.
Appendix: source
Thrown at kernel/model/assets.go:548
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,
})
if err != nil {
return GenerateDocumentImageResult{}, err
}View on GitHub (pinned to 9f775e8a12)