siyuan-note/siyuan · error

Input can not be empty

Error message

Input can not be empty

What it means

SetCriterion persists a named saved-search criterion. Before acquiring the criteria lock it requires criterion.Name to be a non-empty string; when the name is empty it returns the localized 'Input can not be empty' message (Conf.Language(142)). Criteria are keyed by name, so an empty name would be unusable and ambiguous.

Solutions

  1. Set criterion.Name to a non-empty string before calling SetCriterion
  2. In the caller UI, require the user to enter a name and block submission while empty
  3. Generate a default name (e.g. timestamped) when the user omits one

Example fix

// before
model.SetCriterion(&Criterion{})
// after
model.SetCriterion(&Criterion{Name: "My saved search", Criterion: ...})
Defensive patterns

Strategy: validation

Validate before calling

if (!criterion || !criterion.Name || !criterion.Name.trim()) {
  throw new Error("Criterion name is required");
}

Type guard

function hasName(c) { return typeof c?.Name === "string" && c.Name.length > 0; }

Prevention

When it happens

Trigger: Calling kernel API /api/storage/setCriterion with a Criterion object whose Name field is "" or missing; frontend saving a search query without the user entering a name.

Common situations: A plugin automates criterion saving and leaves Name unset; UI dialog submitted without validation; a refactored struct field renamed so Name no longer populated.

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/e60bd76a183b1f04. Report an issue: GitHub.

Appendix: source

Thrown at kernel/model/storage.go:206

	U                 bool `json:"u"`
	DocTitle          bool `json:"docTitle"`
	CodeBlock         bool `json:"codeBlock"`
	MathBlock         bool `json:"mathBlock"`
	HtmlBlock         bool `json:"htmlBlock"`
}

var criteriaLock = sync.Mutex{}

func GetCriteria() (ret []*Criterion) {
	criteriaLock.Lock()
	defer criteriaLock.Unlock()
	ret, _ = getCriteria()
	return
}

func SetCriterion(criterion *Criterion) (err error) {
	if "" == criterion.Name {
		return errors.New(Conf.Language(142))
	}

	criteriaLock.Lock()
	defer criteriaLock.Unlock()

	criteria, err := getCriteria()
	if err != nil {
		return
	}

	update := false
	for i, c := range criteria {
		if c.Name == criterion.Name {
			criteria[i] = criterion
			update = true
			break
		}
	}

View on GitHub (pinned to 9f775e8a12)