{"record":{"id":"2de2648df1b87dcd","repo":"siyuan-note/siyuan","slug":"invalid-attribute-view-context-filter","errorCode":null,"errorMessage":"invalid attribute view context filter","messagePattern":"invalid attribute view context filter","errorType":"error_code","errorClass":null,"httpStatus":null,"severity":"error","filePath":"kernel/av/context_filter.go","lineNumber":31,"sourceCode":"//\n// You should have received a copy of the GNU Affero General Public License\n// along with this program.  If not, see <https://www.gnu.org/licenses/>.\n\npackage av\n\nimport (\n\t\"bytes\"\n\t\"encoding/json\"\n\t\"errors\"\n\t\"fmt\"\n\t\"io\"\n\t\"strings\"\n)\n\nconst AttributeViewContextFilterSpec = 1\n\nvar (\n\tErrInvalidAttributeViewContextFilter = errors.New(\"invalid attribute view context filter\")\n\tErrAttributeViewContextNotBound      = errors.New(\"current document is not bound to the context filter target database\")\n)\n\n// AttributeViewContextFilter 描述物理数据库块独有的上下文筛选配置。\ntype AttributeViewContextFilter struct {\n\tSpec  int    `json:\"spec\"`\n\tKeyID string `json:\"keyID\"`\n}\n\n// AttributeViewContextFilterField 描述可用于物理数据库块上下文筛选的关联字段。\ntype AttributeViewContextFilterField struct {\n\tID         string `json:\"id\"`\n\tName       string `json:\"name\"`\n\tIcon       string `json:\"icon\"`\n\tTargetAvID string `json:\"targetAvID\"`\n}\n\n// FilterContext 保存一次数据库块渲染所需的上下文筛选值，不参与持久化。","sourceCodeStart":13,"sourceCodeEnd":49,"githubUrl":"https://github.com/siyuan-note/siyuan/blob/9f775e8a12daef8255556097396f9b2739078892/kernel/av/context_filter.go#L13-L49","documentation":"ErrInvalidAttributeViewContextFilter is the sentinel error for a malformed attribute view context filter — the per-physical-database-block filter configuration. ParseAttributeViewContextFilter returns it (wrapped with decode details) when the JSON cannot be decoded, and Validate returns it when the decoded filter has the wrong spec version or an empty KeyID.","triggerScenarios":"Calling ParseAttributeViewContextFilter with JSON that fails to decode (line 66), or with JSON whose spec != AttributeViewContextFilterSpec (currently 1) or whose keyID is blank/whitespace (line 75).","commonSituations":"Filter blobs written by older/newer kernel versions with a different spec number; hand-crafted or truncated JSON stored on the block; a database block whose keyID was never populated or was cleared by an edit.","solutions":["Check the wrapped %v detail when it comes from decoding — fix the JSON syntax","Ensure the filter JSON has \"spec\": 1 matching AttributeViewContextFilterSpec","Populate keyID with the target database's key identifier; regenerate the filter blob if corrupt"],"exampleFix":"// before\n{\"spec\":2,\"keyID\":\"\"}\n// after\n{\"spec\":1,\"keyID\":\"20240101120000-abcdefg\"}","handlingStrategy":"validation","validationCode":"var f map[string]interface{}\nif err := json.Unmarshal(raw, &f); err != nil { return err }\nif f[\"spec\"] != float64(av.AttributeViewContextFilterSpec) { return errors.New(\"bad spec\") }\nkeyID, _ := f[\"keyID\"].(string)\nif strings.TrimSpace(keyID) == \"\" { return errors.New(\"empty keyID\") }","typeGuard":null,"tryCatchPattern":"filter, err := av.ParseAttributeViewContextFilter(raw)\nif err != nil {\n    if errors.Is(err, av.ErrInvalidAttributeViewContextFilter) { regenerateFilter(block) }\n}","preventionTips":["Always emit \"spec\": 1 exactly as AttributeViewContextFilterSpec","Never persist a filter with an empty keyID","Regenerate filter blobs from the source database instead of hand-editing JSON"],"tags":["attribute-view","filter","validation"],"backgroundTag":"schema-validation-failed","analyzedSha":"9f775e8a12daef8255556097396f9b2739078892","analyzedAt":"2026-09-19T03:17:15.984Z","contentChangedAt":"2026-09-19T03:17:15.984Z","schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}