{"record":{"id":"055de086a32d7980","repo":"siyuan-note/siyuan","slug":"filter-nesting-depth-exceeds-the-maximum-allowed","errorCode":null,"errorMessage":"filter nesting depth exceeds the maximum allowed","messagePattern":"filter nesting depth exceeds the maximum allowed","errorType":"validation","errorClass":"ErrFilterTooDeep","httpStatus":null,"severity":"error","filePath":"kernel/av/av.go","lineNumber":1302,"sourceCode":"\t}\n\treturn\n}\n\nfunc GetAttributeViewI18n(key string) string {\n\treturn util.AttrViewLangs[util.Lang][key].(string)\n}\n\nvar (\n\tErrAttributeViewNotFound  = errors.New(\"attribute view not found\")\n\tErrInvalidAttributeViewID = errors.New(\"invalid attribute view id\")\n\tErrInvalidBoxID           = errors.New(\"invalid box id\")\n\tErrViewNotFound           = errors.New(\"view not found\")\n\tErrKeyNotFound            = errors.New(\"key not found\")\n\tErrItemNotFound           = errors.New(\"item not found\")\n\tErrWrongLayoutType        = errors.New(\"wrong layout type\")\n\tErrInvalidColumnAlign     = errors.New(\"invalid column align\")\n\tErrSpecTooNew             = errors.New(\"attribute view spec is too new\")\n\tErrFilterTooDeep          = errors.New(\"filter nesting depth exceeds the maximum allowed\")\n)\n\nconst (\n\tNodeAttrNameAvs        = \"custom-avs\"                 // 用于标记块所属的属性视图，逗号分隔 av id\n\tNodeAttrView           = \"custom-sy-av-view\"          // 用于标记块所属的属性视图视图 view id Database block support specified view https://github.com/siyuan-note/siyuan/issues/10443\n\tNodeAttrVisibleViewIDs = \"custom-sy-av-visible-views\" // 用于标记数据库块显示的视图 ID，逗号分隔\n\tNodeAttrViewStaticText = \"custom-sy-av-s-text\"        // 用于标记块所属的属性视图静态文本 Database-bound block primary key supports setting static anchor text https://github.com/siyuan-note/siyuan/issues/10049\n\n\tNodeAttrViewNames = \"av-names\" // 用于临时标记块所属的属性视图名称，空格分隔\n)\n","sourceCodeStart":1284,"sourceCodeEnd":1313,"githubUrl":"https://github.com/siyuan-note/siyuan/blob/afa823b6b4e4f183511e0bc0a3be93caa94c7c97/kernel/av/av.go#L1284-L1313","documentation":"ErrFilterTooDeep is returned by ValidateFilterDepth / validateFilterNodeDepth (kernel/av/filter.go:152-173) when a filter group tree nests deeper than MaxFilterNestingDepth = 3 (kernel/av/av_fix.go:29). It guards against stack exhaustion and pathological evaluation on the recursive filter structure introduced with spec-5 grouped filters.","triggerScenarios":"Submitting a setAttrViewFilters operation whose ViewFilter group chain (Filter.Combination groups containing groups) exceeds depth 3; replaying or hand-crafting a deeply nested filters array in the .av.json; a plugin building filters recursively from user input without a depth cap.","commonSituations":"Programmatically composed filter trees (e.g. converting a boolean expression to nested AND/OR groups) that exceed 3 levels; imported or synced database definitions that were produced by a tool without the depth limit.","solutions":["Flatten the filter tree: since spec 5 a single root group exists (normalizeFiltersAsRoot), push leaf conditions into fewer, wider groups instead of deep chains","Cap recursion at 3 when generating filters client-side and AND-merge anything deeper into the nearest group","Run av.ValidateFilterDepth(filters) before persisting if you construct []*av.ViewFilter directly in Go"],"exampleFix":"// before: nesting groups 5 deep\nfilters := group(and, group(or, group(and, group(or, leaves...))))\n\n// after: flatten to max depth 3, widen the root group\nfilters := group(and,\n    leaf(cond1), leaf(cond2),\n    group(or, leaf(cond3), leaf(cond4)),\n)","handlingStrategy":"validation","validationCode":"func clampFilterDepth(node *av.ViewFilter, depth int) *av.ViewFilter {\n    if nil == node || !node.IsGroup() || depth >= 3 {\n        return node // stop nesting here; merge leaves into this group\n    }\n    for i, child := range node.Filters {\n        node.Filters[i] = clampFilterDepth(child, depth+1)\n    }\n    return node\n}\n_ = av.ValidateFilterDepth(filters) // final check before persisting","typeGuard":"func isFilterTooDeep(err error) bool {\n    return errors.Is(err, av.ErrFilterTooDeep)\n}","tryCatchPattern":null,"preventionTips":["Cap filter-tree builders at MaxFilterNestingDepth (3) and widen groups instead of deepening","Remember spec-5 shape: filters are one root group; prefer breadth (many leaves in one AND/OR group)","Validate filters with av.ValidateFilterDepth before any setAttrViewFilters transaction"],"tags":["siyuan","attribute-view","filter","depth-limit","validation","go"],"backgroundTag":"nesting-depth-limit-exceeded","analyzedSha":"afa823b6b4e4f183511e0bc0a3be93caa94c7c97","analyzedAt":"2026-08-18T17:04:10.865Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}