{"record":{"id":"daa77e9f28af029e","repo":"siyuan-note/siyuan","slug":"unsupported-rich-clipboard-image-extension-s","errorCode":null,"errorMessage":"unsupported rich clipboard image extension [%s]","messagePattern":"unsupported rich clipboard image extension \\[(.+?)\\]","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"kernel/model/clipboard.go","lineNumber":88,"sourceCode":"\n\tbatch := util.RandString(24)\n\tgroups := map[string]struct{}{}\n\tcopied := map[string]string{}\n\tret = &RichClipboardPrepared{Batch: batch}\n\tdefer func() {\n\t\tif err != nil {\n\t\t\tcleanupRichClipboardGroups(batch, groups)\n\t\t}\n\t}()\n\n\tfor _, asset := range assets {\n\t\tif asset.Index < 0 {\n\t\t\treturn nil, fmt.Errorf(\"invalid rich clipboard asset index [%d]\", asset.Index)\n\t\t}\n\n\t\text := strings.ToLower(filepath.Ext(AssetPathWithoutQuery(asset.Path)))\n\t\tif _, ok := richClipboardImageExts[ext]; !ok {\n\t\t\treturn nil, fmt.Errorf(\"unsupported rich clipboard image extension [%s]\", ext)\n\t\t}\n\n\t\tabsPath, resolveErr := GetAssetAbsPathInBox(asset.Path, asset.Box)\n\t\tif resolveErr != nil {\n\t\t\treturn nil, resolveErr\n\t\t}\n\t\tif ensureErr := ensureReadableAssetLocal(absPath); ensureErr != nil {\n\t\t\treturn nil, ensureErr\n\t\t}\n\n\t\tdestPath, ok := copied[absPath]\n\t\tif !ok {\n\t\t\tgroup := ExtractBoxIDFromAssetsPath(absPath)\n\t\t\tif group == \"\" {\n\t\t\t\tgroup = richClipboardGlobalGroup\n\t\t\t}\n\t\t\tgroups[group] = struct{}{}\n","sourceCodeStart":70,"sourceCodeEnd":106,"githubUrl":"https://github.com/siyuan-note/siyuan/blob/9f775e8a12daef8255556097396f9b2739078892/kernel/model/clipboard.go#L70-L106","documentation":"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).","triggerScenarios":"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).","commonSituations":"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.","solutions":["Filter the asset list to allowed image extensions before calling PrepareRichClipboardAssets; drop or separately handle SVGs","Convert unsupported formats (e.g. SVG) to a supported raster format (PNG) before adding them to the clipboard payload","Check the richClipboardImageExts allowlist in kernel/model/clipboard.go to know exactly which extensions are accepted","Strip query strings from asset URLs before extracting the extension (the kernel already does via AssetPathWithoutQuery, but client-side checks should match)"],"exampleFix":"// before\nassets = append(assets, RichClipboardAsset{Index: i, Path: img.Src}) // may be .svg\n\n// after\next := strings.ToLower(filepath.Ext(model.AssetPathWithoutQuery(img.Src)))\nif _, ok := allowedImageExts[ext]; !ok {\n    continue // skip or convert unsupported types such as SVG\n}","handlingStrategy":"validation","validationCode":"ext := strings.ToLower(filepath.Ext(model.AssetPathWithoutQuery(p)))\nif _, ok := allowedImageExts[ext]; !ok { continue } // skip/convert SVG etc.","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Filter clipboard candidates to the allowlisted image extensions before calling the kernel","Convert SVG and other vector formats to PNG before clipboard copy","Strip query strings before extension checks to mirror kernel behavior"],"tags":["clipboard","file-extension","unsupported-format"],"backgroundTag":"unsupported-operation","analyzedSha":"9f775e8a12daef8255556097396f9b2739078892","analyzedAt":"2026-09-19T03:17:15.984Z","contentChangedAt":"2026-09-19T03:17:15.984Z","schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}