{"record":{"id":"3b9f1844f016145c","repo":"siyuan-note/siyuan","slug":"custom-emoji-name-must-not-be-empty","errorCode":null,"errorMessage":"custom emoji name must not be empty","messagePattern":"custom emoji name must not be empty","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"warning","filePath":"kernel/api/system.go","lineNumber":391,"sourceCode":"\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\")\n\t\t}\n\t\tpart = util.FilterUploadFileName(part)\n\t\tif part == \"\" || part == \".\" || part == \"..\" {\n\t\t\treturn \"\", fmt.Errorf(\"invalid custom emoji name\")\n\t\t}\n\t\tparts[i] = part\n\t}","sourceCodeStart":373,"sourceCodeEnd":409,"githubUrl":"https://github.com/siyuan-note/siyuan/blob/251596fc0de2f9528c00c224252fd073a99973f4/kernel/api/system.go#L373-L409","documentation":"Returned by normalizeCustomEmojiPath when len(parts) == 0 after strings.Split(name, '/'). In practice this branch is unreachable: strings.Split on any string input (including the empty string) returns a slice of at least one element, so len(parts) is never 0. The real empty-name condition is instead caught by the loop below (errors 87/88) where a part trims to empty. This error exists only as a defensive guard.","triggerScenarios":"Not triggerable through the HTTP API under normal Go strings.Split semantics. A caller would need to pass a value that splits to zero parts, which the standard library never produces.","commonSituations":"Effectively dead code. A developer seeing this message in logs should suspect a custom fork that changed the split logic or a non-string input path.","solutions":["Treat an occurrence as a code-smell: the actual empty-name case is handled by the loop below and surfaces as 'invalid custom emoji name' (errors 87/88).","If you are forking, replace this guard with an explicit name == \"\" check before the split to make the intent reachable."],"exampleFix":"// before (current, unreachable)\nparts := strings.Split(name, \"/\")\nif len(parts) == 0 {\n    return \"\", fmt.Errorf(\"custom emoji name must not be empty\")\n}\n\n// after (reachable, clearer intent)\nname = strings.TrimSpace(name)\nif name == \"\" {\n    return \"\", fmt.Errorf(\"custom emoji name must not be empty\")\n}\nparts := strings.Split(name, \"/\")","handlingStrategy":"validation","validationCode":"// The current guard is unreachable; validate explicitly before the split\nname = strings.TrimSpace(name)\nif name == \"\" { return errors.New(\"custom emoji name must not be empty\") }","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Treat this message as a signal of dead code; the real empty-name case is errors 87/88.","If forking, add an explicit name == \"\" check before strings.Split to make the guard reachable.","Do not rely on this branch firing in upstream code."],"tags":["validation","emoji","path","dead-code","api"],"backgroundTag":null,"analyzedSha":"251596fc0de2f9528c00c224252fd073a99973f4","analyzedAt":"2026-08-12T21:18:37.123Z","schemaVersion":2},"datasetVersion":"2026-08-13T04:17:16.726Z"}