siyuan-note/siyuan · error

view IDs is empty

Error message

view IDs is empty

What it means

Thrown by setAttributeViewFieldsHidden when, after iterating and de-duplicating the viewIDs, no fields were collected (len(fields) < 1). This happens when viewIDs is empty to begin with, or every supplied viewID failed the earlier checks and none accumulated a field — the function refuses a no-op hide/show.

Source

Thrown at kernel/model/attribute_view.go:6515

	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 251596fc0d)

Solutions

  1. Require at least one valid viewID before issuing the hide/show operation on the client.
  2. Validate that viewIDs is non-empty and that each entry resolves to a live view containing the field.
  3. If the user deselects all views, skip the operation rather than sending an empty list.

Example fix

// before
transaction([{ action: 'setAttrViewFieldsHidden', avID, keyID, viewIDs: [], hidden: true }])
// after
if (viewIDs.length === 0) return
transaction([{ action: 'setAttrViewFieldsHidden', avID, keyID, viewIDs, hidden: true }])
Defensive patterns

Strategy: validation

Validate before calling

if (!Array.isArray(operation.viewIDs) || operation.viewIDs.length === 0) { /* skip the op entirely */ }

Type guard

function nonEmptyViewIDs(v: unknown): v is string[] {
  return Array.isArray(v) && v.every(x => typeof x === 'string') && v.length > 0
}

Prevention

When it happens

Trigger: Calling the hide/show operation with an empty viewIDs slice; passing only invalid/duplicate viewIDs that all resolve to nil views or missing fields; an undo replay whose view list was already consumed.

Common situations: Frontend 'hide field' button firing before any view was selected; bulk operation built from an empty selection set; defensive guard tripping after upstream filtering removed all entries.

Related errors


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