siyuan-note/siyuan · error
unsupported rich clipboard image extension [%s]
Error message
unsupported rich clipboard image extension [%s]
What it means
Returned by PrepareRichClipboardAssets when the file extension of an asset path is not in the richClipboardImageExts allow-list. The extension is extracted via filepath.Ext after lowercasing and after stripping any query string via AssetPathWithoutQuery. Only image types registered in that map are accepted for rich clipboard copying.
Source
Thrown at kernel/model/clipboard.go:88
batch := util.RandString(24)
groups := map[string]struct{}{}
copied := map[string]string{}
ret = &RichClipboardPrepared{Batch: batch}
defer func() {
if err != nil {
cleanupRichClipboardGroups(batch, groups)
}
}()
for _, asset := range assets {
if asset.Index < 0 {
return nil, fmt.Errorf("invalid rich clipboard asset index [%d]", asset.Index)
}
ext := strings.ToLower(filepath.Ext(AssetPathWithoutQuery(asset.Path)))
if _, ok := richClipboardImageExts[ext]; !ok {
return nil, fmt.Errorf("unsupported rich clipboard image extension [%s]", ext)
}
absPath, resolveErr := GetAssetAbsPathInBox(asset.Path, asset.Box)
if resolveErr != nil {
return nil, resolveErr
}
destPath, ok := copied[absPath]
if !ok {
group := ExtractBoxIDFromAssetsPath(absPath)
if group == "" {
group = richClipboardGlobalGroup
}
groups[group] = struct{}{}
destDir := filepath.Join(util.TempDir, "clipboard", group, batch)
if mkdirErr := os.MkdirAll(destDir, 0700); mkdirErr != nil {
return nil, mkdirErrView on GitHub (pinned to 251596fc0d)
Solutions
- Filter the assets array on the frontend to only include image extensions the server supports (PNG, JPG, GIF, etc.) before calling.
- If you need a format that is rejected, add it to the richClipboardImageExts map (kernel change) or convert the asset to a supported format.
- Confirm AssetPathWithoutQuery is applied client-side too so query strings do not corrupt extension detection.
Example fix
// before: send everything
assets = append(assets, RichClipboardAsset{Path: anyPath})
// after: filter to supported image extensions
var allowed = map[string]bool{".png": true, ".jpg": true, ".jpeg": true, ".gif": true, ".webp": true}
for _, p := range paths {
ext := strings.ToLower(filepath.Ext(p))
if allowed[ext] {
assets = append(assets, RichClipboardAsset{Path: p})
}
} Defensive patterns
Strategy: validation
Validate before calling
var richClipboardImageExts = map[string]bool{".png":true,".jpg":true,".jpeg":true,".gif":true,".webp":true,".bmp":true,".svg":true}
func supportedImageExt(path string) bool {
ext := strings.ToLower(filepath.Ext(stripQuery(path)))
return richClipboardImageExts[ext]
} Type guard
func isSupportedImage(path string) bool { return supportedImageExt(path) } Try / catch
if err != nil && strings.Contains(err.Error(), "unsupported rich clipboard image extension") { filterToImagesAndRetry() } Prevention
- Mirror the server's allow-list on the client and filter before sending.
- Convert unsupported formats to PNG/JPG before clipboard preparation.
- Strip query strings before extracting extensions.
When it happens
Trigger: An asset path points to a non-image file (e.g. .pdf, .docx) or an image format not in the allow-list (e.g. a less common format), or the path has no extension at all. The check runs per asset after the index validation.
Common situations: Paste handler collected a file reference that is not an image; user copied content containing an embedded SVG or HEIC that is not whitelisted; asset URL carries a query string that, even after stripping, leaves an unsupported extension.
Related errors
- invalid rich clipboard asset count [%d]
- invalid rich clipboard asset index [%d]
- assetPath is required for analyze
- only local assets/... images are supported
- assetPath is not an image referenced by the document
AI-assisted analysis of siyuan-note/siyuan@251596fc0d (2026-08-12).
Data as JSON: /api/errors/daa77e9f28af029e.
Report an issue: GitHub.