siyuan-note/siyuan · error

filter nesting depth exceeds the maximum allowed

Error message

filter nesting depth exceeds the maximum allowed

What it means

Sentinel ErrFilterTooDeep. Returned by validateFilterNodeDepth (av/filter.go:169) when a group filter (AND/OR combination) is nested deeper than MaxFilterNestingDepth (3). ValidateFilterDepth walks each top-level filter and recurses into group children; exceeding depth 3 aborts to prevent pathological/expensive filter trees.

Source

Thrown at kernel/av/av.go:1302

	}
	return
}

func GetAttributeViewI18n(key string) string {
	return util.AttrViewLangs[util.Lang][key].(string)
}

var (
	ErrAttributeViewNotFound  = errors.New("attribute view not found")
	ErrInvalidAttributeViewID = errors.New("invalid attribute view id")
	ErrInvalidBoxID           = errors.New("invalid box id")
	ErrViewNotFound           = errors.New("view not found")
	ErrKeyNotFound            = errors.New("key not found")
	ErrItemNotFound           = errors.New("item not found")
	ErrWrongLayoutType        = errors.New("wrong layout type")
	ErrInvalidColumnAlign     = errors.New("invalid column align")
	ErrSpecTooNew             = errors.New("attribute view spec is too new")
	ErrFilterTooDeep          = errors.New("filter nesting depth exceeds the maximum allowed")
)

const (
	NodeAttrNameAvs        = "custom-avs"                 // 用于标记块所属的属性视图,逗号分隔 av id
	NodeAttrView           = "custom-sy-av-view"          // 用于标记块所属的属性视图视图 view id Database block support specified view https://github.com/siyuan-note/siyuan/issues/10443
	NodeAttrVisibleViewIDs = "custom-sy-av-visible-views" // 用于标记数据库块显示的视图 ID,逗号分隔
	NodeAttrViewStaticText = "custom-sy-av-s-text"        // 用于标记块所属的属性视图静态文本 Database-bound block primary key supports setting static anchor text https://github.com/siyuan-note/siyuan/issues/10049

	NodeAttrViewNames = "av-names" // 用于临时标记块所属的属性视图名称,空格分隔
)

View on GitHub (pinned to 251596fc0d)

Solutions

  1. Flatten the filter tree to at most 3 levels of grouping before submitting.
  2. Combine sibling predicates under one group instead of wrapping each predicate in its own group.
  3. Add a client-side depth check mirroring MaxFilterNestingDepth (3) to reject deep trees before the round trip.

Example fix

// before
// deeply nested: AND( OR( AND( OR( p1, p2 ) ) ) )  -> depth 4 -> filter too deep
filter := &av.ViewFilter{Combination: "and", Filters: []*av.ViewFilter{
    {Combination: "or", Filters: []*av.ViewFilter{
        {Combination: "and", Filters: []*av.ViewFilter{
            {Combination: "or", Filters: []*av.ViewFilter{p1, p2}},
        }},
    }},
}}

// after: flatten to <= 3 levels
filter := &av.ViewFilter{Combination: "and", Filters: []*av.ViewFilter{
    {Combination: "or", Filters: []*av.ViewFilter{p1, p2}},
}}
Defensive patterns

Strategy: validation

Validate before calling

// Enforce the depth cap client-side before submitting
const MAX_DEPTH = 3
func checkDepth(f *av.ViewFilter, depth int) error {
    if f == nil || !f.IsGroup() { return nil }
    if depth > MAX_DEPTH { return errors.New("filter too deep") }
    for _, c := range f.Filters { if e := checkDepth(c, depth+1); e != nil { return e } }
    return nil
}
for _, f := range filters { if e := checkDepth(f, 1); e != nil { return e } }

Prevention

When it happens

Trigger: Submitting a setfilter operation (or saving a view) whose filter tree nests groups more than 3 levels: e.g. an AND group containing an OR group containing an AND group containing another group. The client constructed a deeply nested combination.

Common situations: A UI that lets users nest filter groups arbitrarily without a depth cap; a plugin importing an external query as a deep filter tree; programmatic construction that wraps every predicate in its own group.

Related errors


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