siyuan-note/siyuan · error

view IDs is empty

Error message

view IDs is empty

What it means

The hide/show-fields operation requires at least one resolved field. If the fields list ends up empty — because the viewIDs/keyID inputs produced no valid entries — the kernel rejects the call with this fixed-message error.

Solutions

  1. Pass at least one valid view ID in viewIDs
  2. Guard the caller: skip the API call when the selection is empty
  3. Check earlier resolution logic so valid entries are not silently dropped

Example fix

// before
if (selectedViews.length) { /* do nothing anyway */ }
setAttrViewFieldHidden(avID, [], keyID, hidden)
// after
if (!selectedViews.length) return; // guard instead of calling
setAttrViewFieldHidden(avID, selectedViews, keyID, hidden)
Defensive patterns

Strategy: validation

Validate before calling

if (!viewIDs || viewIDs.length === 0) return; // nothing to do, skip the API call

Type guard

const hasTargets = (ids: unknown): ids is string[] => Array.isArray(ids) && ids.length > 0;

Try / catch

try { await setAttrViewFieldHidden(avID, viewIDs, keyID, hidden); } catch (e) { if (String(e).includes("view IDs is empty")) { console.warn("no views selected; skipping"); } else throw e; }

Prevention

When it happens

Trigger: Calling the API with an empty viewIDs array, or with inputs whose every entry failed resolution before reaching this check.

Common situations: Plugins calling with an empty selection (no views picked); loops filtered out all IDs due to earlier validation; blank/default parameters from unbound UI state.

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

Appendix: source

Thrown at kernel/model/attribute_view.go:6996

	for _, viewID := range viewIDs {
		if seen[viewID] {
			continue
		}
		seen[viewID] = true

		view := attrView.GetView(viewID)
		if nil == view {
			return fmt.Errorf("view [%s] not found", viewID)
		}
		field := getAttributeViewField(view, keyID)
		if nil == field {
			return fmt.Errorf("field [%s] not found in view [%s]", keyID, viewID)
		}
		fields = append(fields, field)
	}

	if 1 > len(fields) {
		return errors.New("view IDs is empty")
	}
	for _, field := range fields {
		field.Hidden = hidden
	}
	return
}

func getAttributeViewField(view *av.View, keyID string) (ret *av.BaseField) {
	switch view.LayoutType {
	case av.LayoutTypeTable:
		if nil == view.Table {
			return
		}
		for _, column := range view.Table.Columns {
			if column.ID == keyID {
				return column.BaseField
			}
		}

View on GitHub (pinned to 9f775e8a12)