{"record":{"id":"01fd76249aa59638","repo":"siyuan-note/siyuan","slug":"validate-attribute-view-context-filter-target-w","errorCode":null,"errorMessage":"validate attribute view context filter target: %w","messagePattern":"validate attribute view context filter target: %w","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"kernel/model/attribute_view.go","lineNumber":5511,"sourceCode":"\tif nil != err {\n\t\treturn nil, err\n\t}\n\tnode, tree, err := getAttributeViewInstanceNode(attrView, blockID)\n\tif nil != err {\n\t\treturn nil, err\n\t}\n\n\tvar value string\n\tkeyID = strings.TrimSpace(keyID)\n\tif \"\" != keyID {\n\t\tret = &av.AttributeViewContextFilter{Spec: av.AttributeViewContextFilterSpec, KeyID: keyID}\n\t\t// undo/redo 重放需要能恢复字段删除或改型后留下的旧配置；普通事务和公开 API 仍严格校验。\n\t\tif nil == tx || !tx.isReplay {\n\t\t\tif err = ret.Validate(attrView); nil != err {\n\t\t\t\treturn nil, err\n\t\t\t}\n\t\t\tif _, err = resolveAttributeViewContextFilterTarget(attrView, ret, tree.Box); nil != err {\n\t\t\t\treturn nil, fmt.Errorf(\"validate attribute view context filter target: %w\", err)\n\t\t\t}\n\t\t}\n\t\tif value, err = ret.Marshal(); nil != err {\n\t\t\treturn nil, err\n\t\t}\n\t}\n\tif value == node.IALAttr(av.NodeAttrContextFilter) {\n\t\treturn\n\t}\n\n\tattrs := map[string]string{av.NodeAttrContextFilter: value}\n\tif nil != tx {\n\t\terr = setNodeAttrsWithTx(tx, node, tree, attrs)\n\t} else {\n\t\terr = setNodeAttrs(node, tree, attrs)\n\t}\n\treturn\n}","sourceCodeStart":5493,"sourceCodeEnd":5529,"githubUrl":"https://github.com/siyuan-note/siyuan/blob/8641553a1f07374001902d3ce773285db1292b2d/kernel/model/attribute_view.go#L5493-L5529","documentation":"Wraps resolveAttributeViewContextFilterTarget when a newly validated context filter cannot be resolved against the attribute view and its tree box. Validation passed, but finding the filter's concrete target (e.g. the referenced view/field) failed, so the kernel refuses to persist the filter. Skipped during undo/redo replay so historical configurations can still be restored.","triggerScenarios":"Calling SetAttributeViewContextFilter with a keyID/filter whose target cannot be resolved in the current attribute view — typically referencing a field that no longer exists (or exists in a different view) in a non-replay transaction.","commonSituations":"Setting a filter referencing a deleted or renamed field; passing a keyID from another attribute view; a plugin restoring filters after fields were restructured.","solutions":["Confirm the keyID exists in the target attribute view before setting the filter (list fields via API)","Re-create the missing field or choose an existing field as the filter target","If restoring legacy configs, ensure the referenced fields are recreated with the same IDs first"],"exampleFix":"// before\nsetAvContextFilter(blockID, avID, removedKeyID);\n// after\nconst keys = await getAvKeys(avID);\nif (!keys.some(k => k.id === keyID)) throw new Error(\"key gone\");\nsetAvContextFilter(blockID, avID, keyID);","handlingStrategy":"validation","validationCode":"const keys = await getAvKeys(avID);\nif (!keys.some(k => k.id === keyID)) throw new Error(`filter target key ${keyID} missing`);","typeGuard":null,"tryCatchPattern":"try { await setAvContextFilter(blockID, avID, keyID); } catch (e) { if (String(e).includes(\"filter target\")) await recreateFieldThenRetry(); else throw e; }","preventionTips":["Validate filter targets exist before persisting filters","Recreate referenced fields before restoring legacy filter configs","Only reference keyIDs from the same attribute view"],"tags":["attribute-view","context-filter","validation"],"backgroundTag":"invalid-argument-value","analyzedSha":"8641553a1f07374001902d3ce773285db1292b2d","analyzedAt":"2026-09-11T16:08:28.414Z","contentChangedAt":"2026-09-11T16:08:28.414Z","schemaVersion":2},"datasetVersion":"2026-09-14T05:17:10.506Z"}