siyuan-note/siyuan · error

save generated image failed

Error message

save generated image failed: %w

What it means

After a successful GenerateImage call, GenerateDocumentImage persists the resulting bytes into the document's assets via InsertAssetBytes(bt.RootID, "ai-image"+generated.Extension, generated.Data). If that insertion fails (write error, invalid root block, asset storage problem), the failure is wrapped as "save generated image failed: %w" and marked execution-unknown because the provider already produced the image.

Solutions

  1. Check the wrapped cause: restore the document if it was deleted, or retry against an existing document
  2. Verify the workspace data/assets directory is writable and has free space
  3. Retry the generation; since the image already exists upstream, prefer re-saving with InsertAssetBytes using the cached bytes if available
  4. Resolve sync conflicts on the target document before retrying

Example fix

// before
bt := resolve doc by stale ID; InsertAssetBytes(bt.RootID, ...) // document deleted
// after
if treenode.GetBlockTree(docID) == nil { return errors.New("document missing; reselect target") }
assetPath, _, err := model.InsertAssetBytes(bt.RootID, "ai-image"+ext, data)
Defensive patterns

Strategy: try-catch

Validate before calling

if treenode.GetBlockTree(docID) == nil {
    return errors.New("target document missing; aborting image save")
}
if err := util.IsWorkspaceReadOnly(); err != nil { return err } // if applicable

Try / catch

res, err := model.GenerateDocumentImage(docID, req)
if err != nil && strings.Contains(err.Error(), "save generated image failed") {
    // image bytes were already generated; check disk space/permissions, then retry save
}

Prevention

When it happens

Trigger: InsertAssetBytes fails: the document root block (bt.RootID) no longer exists or its tree cannot be written, the assets directory is not writable, the disk is full, or the file lock cannot be acquired.

Common situations: The target document was deleted by another client while generation was in flight; running the kernel with a read-only workspace; disk quota exhaustion; concurrent sync writing the same asset path.

Understand the failure class

Background: "failed to write file", "Could not save figure", "Error saving remote file" — file write failed: causes and fixes across languages and libraries — this error's family across 38 libraries.

Related errors


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

Appendix: source

Thrown at kernel/model/assets.go:569

		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
	}
	assetPath, _, err := InsertAssetBytes(bt.RootID, "ai-image"+generated.Extension, generated.Data)
	if err != nil {
		return GenerateDocumentImageResult{}, markImageExecutionUnknown(fmt.Errorf("save generated image failed: %w", err))
	}
	return GenerateDocumentImageResult{
		Artifact: ImageArtifactRef{
			Kind: "image", Path: assetPath, MIMEType: generated.MIMEType, DocumentID: bt.RootID,
		},
		RevisedPrompt: generated.RevisedPrompt,
	}, nil
}

func resolveMultimodalDocument(documentID string) (*treenode.BlockTree, error) {
	bt := treenode.GetBlockTree(strings.TrimSpace(documentID))
	if bt == nil {
		return nil, errors.New("document not found: " + documentID)
	}
	return bt, nil
}

func validateImageModel(provider *conf.Provider, imageModel *conf.Model) error {

View on GitHub (pinned to 9f775e8a12)