siyuan-note/siyuan · warning
custom emoji name must not be empty
Error message
custom emoji name must not be empty
What it means
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.
Source
Thrown at kernel/api/system.go:391
if decodeErr != nil || config.Width < 1 || config.Height < 1 || config.Width > 16384 || config.Height > 16384 ||
int64(config.Width)*int64(config.Height) > 100*1000*1000 {
return nil, "", fmt.Errorf("invalid custom emoji image")
}
return data, ext, nil
}
sanitizedSVG, sanitizeErr := util.SanitizeSVG(string(data))
if sanitizeErr == nil {
return []byte(sanitizedSVG), ".svg", nil
}
return nil, "", fmt.Errorf("unsupported custom emoji image format")
}
func normalizeCustomEmojiPath(name, ext string) (string, error) {
name = strings.TrimSpace(strings.ReplaceAll(name, "\\", "/"))
parts := strings.Split(name, "/")
if len(parts) == 0 {
return "", fmt.Errorf("custom emoji name must not be empty")
}
lastIndex := len(parts) - 1
switch strings.ToLower(filepath.Ext(parts[lastIndex])) {
case ".png", ".jpg", ".jpeg", ".gif", ".webp", ".svg":
parts[lastIndex] = strings.TrimSuffix(parts[lastIndex], filepath.Ext(parts[lastIndex]))
}
for i, part := range parts {
part = strings.TrimSpace(part)
if part == "" || part == "." || part == ".." {
return "", fmt.Errorf("invalid custom emoji name")
}
part = util.FilterUploadFileName(part)
if part == "" || part == "." || part == ".." {
return "", fmt.Errorf("invalid custom emoji name")
}
parts[i] = part
}View on GitHub (pinned to 251596fc0d)
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.
Example fix
// before (current, unreachable)
parts := strings.Split(name, "/")
if len(parts) == 0 {
return "", fmt.Errorf("custom emoji name must not be empty")
}
// after (reachable, clearer intent)
name = strings.TrimSpace(name)
if name == "" {
return "", fmt.Errorf("custom emoji name must not be empty")
}
parts := strings.Split(name, "/") Defensive patterns
Strategy: validation
Validate before calling
// The current guard is unreachable; validate explicitly before the split
name = strings.TrimSpace(name)
if name == "" { return errors.New("custom emoji name must not be empty") } Prevention
- 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.
When it happens
Trigger: 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.
Common situations: 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.
Related errors
- custom emoji file is too large
- custom emoji file must not be empty
- invalid custom emoji image
- unsupported custom emoji image format
- invalid custom emoji name
AI-assisted analysis of siyuan-note/siyuan@251596fc0d (2026-08-12).
Data as JSON: /api/errors/3b9f1844f016145c.
Report an issue: GitHub.