{"record":{"id":"27012c04f9b390e9","repo":"siyuan-note/siyuan","slug":"unsupported-custom-emoji-image-format","errorCode":null,"errorMessage":"unsupported custom emoji image format","messagePattern":"unsupported custom emoji image format","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"kernel/api/system.go","lineNumber":384,"sourceCode":"\tcase \"image/webp\":\n\t\text = \".webp\"\n\tdefault:\n\t\traster = false\n\t}\n\tif raster {\n\t\tconfig, _, decodeErr := image.DecodeConfig(bytes.NewReader(data))\n\t\tif decodeErr != nil || config.Width < 1 || config.Height < 1 || config.Width > 16384 || config.Height > 16384 ||\n\t\t\tint64(config.Width)*int64(config.Height) > 100*1000*1000 {\n\t\t\treturn nil, \"\", fmt.Errorf(\"invalid custom emoji image\")\n\t\t}\n\t\treturn data, ext, nil\n\t}\n\n\tsanitizedSVG, sanitizeErr := util.SanitizeSVG(string(data))\n\tif sanitizeErr == nil {\n\t\treturn []byte(sanitizedSVG), \".svg\", nil\n\t}\n\treturn nil, \"\", fmt.Errorf(\"unsupported custom emoji image format\")\n}\n\nfunc normalizeCustomEmojiPath(name, ext string) (string, error) {\n\tname = strings.TrimSpace(strings.ReplaceAll(name, \"\\\\\", \"/\"))\n\tparts := strings.Split(name, \"/\")\n\tif len(parts) == 0 {\n\t\treturn \"\", fmt.Errorf(\"custom emoji name must not be empty\")\n\t}\n\n\tlastIndex := len(parts) - 1\n\tswitch strings.ToLower(filepath.Ext(parts[lastIndex])) {\n\tcase \".png\", \".jpg\", \".jpeg\", \".gif\", \".webp\", \".svg\":\n\t\tparts[lastIndex] = strings.TrimSuffix(parts[lastIndex], filepath.Ext(parts[lastIndex]))\n\t}\n\tfor i, part := range parts {\n\t\tpart = strings.TrimSpace(part)\n\t\tif part == \"\" || part == \".\" || part == \"..\" {\n\t\t\treturn \"\", fmt.Errorf(\"invalid custom emoji name\")","sourceCodeStart":366,"sourceCodeEnd":402,"githubUrl":"https://github.com/siyuan-note/siyuan/blob/251596fc0de2f9528c00c224252fd073a99973f4/kernel/api/system.go#L366-L402","documentation":"Returned by normalizeCustomEmojiData as the final fallback: http.DetectContentType did not recognize the bytes as png/jpeg/gif/webp (raster=false) AND util.SanitizeSVG rejected the bytes as an SVG. The data is neither a supported raster nor a sanitizable SVG.","triggerScenarios":"Uploading a BMP, TIFF, ICO, AVIF, HEIC, or a text/binary blob; or an SVG that fails sanitization (contains script, external refs, or malformed XML that SanitizeSVG rejects).","commonSituations":"User drops a .bmp or .tiff thinking it is supported; a SVG with embedded <script> or external entity that the sanitizer refuses; a file with a .svg extension but non-XML content.","solutions":["Convert the image to one of png/jpeg/gif/webp, or to a clean hand-authored SVG.","If the source is SVG, remove <script>, on* handlers, external hrefs, and DOCTYPE/entity declarations, then retry.","Run the file through `file` to see its true type and re-export accordingly."],"exampleFix":"// before\n// uploading a BMP file -> 'unsupported custom emoji image format'\n\n// after: convert to a supported format\n//   convert emoji.bmp emoji.png   (ImageMagick)\n// then upload emoji.png","handlingStrategy":"validation","validationCode":"// Confirm the content type is one of the accepted formats before uploading\nct := http.DetectContentType(data)\nswitch ct {\ncase \"image/png\", \"image/jpeg\", \"image/gif\", \"image/webp\":\n    // ok raster\ncase \"image/svg+xml\", \"text/xml; charset=utf-8\":\n    // candidate SVG; ensure it sanitizes\n    if _, e := util.SanitizeSVG(string(data)); e != nil { return e }\ndefault:\n    return fmt.Errorf(\"unsupported content type %s\", ct)\n}","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Convert BMP/TIFF/ICO/AVIF/HEIC to png or webp first.","For SVG, remove scripts, external refs, and DOCTYPE entities before upload.","Match the file extension to the actual content type."],"tags":["validation","emoji","image-format","svg","api"],"backgroundTag":null,"analyzedSha":"251596fc0de2f9528c00c224252fd073a99973f4","analyzedAt":"2026-08-12T21:18:37.123Z","schemaVersion":2},"datasetVersion":"2026-08-13T04:17:16.726Z"}