siyuan-note/siyuan · error

custom emoji name must not be empty

Error message

custom emoji name must not be empty

What it means

normalizeCustomEmojiPath builds a safe relative path from the user-supplied emoji name. Because strings.Split never returns an empty slice, the len(parts)==0 guard is effectively defensive; the error 'custom emoji name must not be empty' signals that no usable name/path was supplied for the emoji.

Solutions

  1. Supply a non-empty emoji name in the request
  2. Trim and validate the name on the client before calling the API
  3. Check that the field is not being dropped by your HTTP client serialization
  4. Use a meaningful filename as the emoji name

Example fix

// before
{"name": ""}
// after
{"name": "smile.png"}
Defensive patterns

Strategy: validation

Validate before calling

const name = (form.name || "").trim();
if (!name) throw new Error("emoji name is required");

Try / catch

try {
  await registerEmoji(payload);
} catch (e) {
  if (String(e).includes("name must not be empty")) {
    notifyUser("Provide a non-empty emoji name");
  }
}

Prevention

When it happens

Trigger: Calling the emoji-registration path with an empty/whitespace-only name; after backslash normalization and splitting, no path components remain.

Common situations: Client sends the API an empty name field; frontend form not filled in; scripted API call omitting the name parameter.

Understand the failure class

Background: "must not be empty", "cannot be empty" — required-field validation errors across open-source libraries — this error's family across 41 libraries.

Related errors


AI-assisted analysis of siyuan-note/siyuan@9f775e8a12 (2026-09-19). Data as JSON: /api/errors/3b9f1844f016145c. Report an issue: GitHub.

Appendix: source

Thrown at kernel/api/system.go:399

		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 9f775e8a12)