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

  1. 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).
  2. 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

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


AI-assisted analysis of siyuan-note/siyuan@251596fc0d (2026-08-12). Data as JSON: /api/errors/3b9f1844f016145c. Report an issue: GitHub.