siyuan-note/siyuan · error

unsupported rich clipboard image extension

Error message

unsupported rich clipboard image extension [%s]

What it means

PrepareRichClipboardAssets only accepts image assets whose file extension (lowercased, taken from the path with any query string stripped via AssetPathWithoutQuery) is in the richClipboardImageExts allowlist; otherwise it returns fmt.Errorf("unsupported rich clipboard image extension [%s]", ext) at kernel/model/clipboard.go:88. This prevents clipboard copy from copying non-image files (the tests explicitly confirm SVG is rejected).

Solutions

  1. Filter the asset list to allowed image extensions before calling PrepareRichClipboardAssets; drop or separately handle SVGs
  2. Convert unsupported formats (e.g. SVG) to a supported raster format (PNG) before adding them to the clipboard payload
  3. Check the richClipboardImageExts allowlist in kernel/model/clipboard.go to know exactly which extensions are accepted
  4. Strip query strings from asset URLs before extracting the extension (the kernel already does via AssetPathWithoutQuery, but client-side checks should match)

Example fix

// before
assets = append(assets, RichClipboardAsset{Index: i, Path: img.Src}) // may be .svg

// after
ext := strings.ToLower(filepath.Ext(model.AssetPathWithoutQuery(img.Src)))
if _, ok := allowedImageExts[ext]; !ok {
    continue // skip or convert unsupported types such as SVG
}
Defensive patterns

Strategy: validation

Validate before calling

ext := strings.ToLower(filepath.Ext(model.AssetPathWithoutQuery(p)))
if _, ok := allowedImageExts[ext]; !ok { continue } // skip/convert SVG etc.

Prevention

When it happens

Trigger: Calling PrepareRichClipboardAssets with an asset path ending in .svg, .pdf, .webm, or any extension not present in richClipboardImageExts; paths where the query-stripping still leaves an unusual extension (e.g. double extensions like .png.txt).

Common situations: Pasting HTML that references SVG images (common from web page copies); clipboard producers that do not filter to raster image types (png/jpg/jpeg/gif/webp depending on the allowlist); assets with uppercase extensions are fine (lowercased) but genuinely non-image types are not.

Understand the failure class

Background: UnsupportedOperationException and "is not supported" errors: when a library deliberately refuses a call — this error's family across 30 libraries.

Related errors


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

Appendix: 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
		}
		if ensureErr := ensureReadableAssetLocal(absPath); ensureErr != nil {
			return nil, ensureErr
		}

		destPath, ok := copied[absPath]
		if !ok {
			group := ExtractBoxIDFromAssetsPath(absPath)
			if group == "" {
				group = richClipboardGlobalGroup
			}
			groups[group] = struct{}{}

View on GitHub (pinned to 9f775e8a12)