{"record":{"id":"9f62cfc7b60ecbc9","repo":"siyuan-note/siyuan","slug":"w-v","errorCode":null,"errorMessage":"%w: %v","messagePattern":"%w: %v","errorType":"validation","errorClass":"ErrInvalidAttributeViewContextFilter","httpStatus":null,"severity":"error","filePath":"kernel/av/context_filter.go","lineNumber":66,"sourceCode":"\n// FilterContext 保存一次数据库块渲染所需的上下文筛选值，不参与持久化。\ntype FilterContext struct {\n\tKeyID                  string\n\tCurrentDocumentItemIDs []string\n}\n\n// ParseAttributeViewContextFilter 从数据库块 IAL 中解析上下文筛选配置。\nfunc ParseAttributeViewContextFilter(data string) (ret *AttributeViewContextFilter, err error) {\n\tdata = strings.TrimSpace(data)\n\tif \"\" == data {\n\t\treturn\n\t}\n\n\tdecoder := json.NewDecoder(bytes.NewBufferString(data))\n\tdecoder.DisallowUnknownFields()\n\tret = &AttributeViewContextFilter{}\n\tif err = decoder.Decode(ret); nil != err {\n\t\terr = fmt.Errorf(\"%w: %v\", ErrInvalidAttributeViewContextFilter, err)\n\t\tret = nil\n\t\treturn\n\t}\n\tif err = ensureAttributeViewContextFilterJSONEOF(decoder); nil != err {\n\t\tret = nil\n\t\treturn\n\t}\n\tif AttributeViewContextFilterSpec != ret.Spec || \"\" == strings.TrimSpace(ret.KeyID) {\n\t\terr = ErrInvalidAttributeViewContextFilter\n\t\tret = nil\n\t}\n\treturn\n}\n\nfunc ensureAttributeViewContextFilterJSONEOF(decoder *json.Decoder) error {\n\tvar trailing any\n\terr := decoder.Decode(&trailing)\n\tif errors.Is(err, io.EOF) {","sourceCodeStart":48,"sourceCodeEnd":84,"githubUrl":"https://github.com/siyuan-note/siyuan/blob/8641553a1f07374001902d3ce773285db1292b2d/kernel/av/context_filter.go#L48-L84","documentation":"ParseAttributeViewContextFilter wraps any JSON decoding failure of a context filter into ErrInvalidAttributeViewContextFilter with the underlying decoder message appended via %w/%v. Decoding uses DisallowUnknownFields, so unknown properties are also rejected.","triggerScenarios":"Calling ParseAttributeViewContextFilter with malformed JSON, wrong JSON types (e.g. spec as string), or extra unknown fields in the payload.","commonSituations":"Hand-edited filter JSON in document attributes; newer format parsed by an older kernel (or vice versa); trailing garbage after the JSON object.","solutions":["Fix the JSON syntax and ensure spec is a number and keyID a string","Remove any unknown properties, since DisallowUnknownFields makes them fatal","Read the wrapped %v detail in the error message to identify the exact decode failure"],"exampleFix":"// before\n{\"spec\": \"1\", \"keyID\": \"k1\", \"extra\": true}\n// after\n{\"spec\": 1, \"keyID\": \"k1\"}","handlingStrategy":"try-catch","validationCode":"function canParseFilterJSON(s) { try { const o = JSON.parse(s); return o && typeof o === 'object' && !('extra' in o); } catch { return false; } }","typeGuard":null,"tryCatchPattern":"filter, err := ParseAttributeViewContextFilter(data)\nif err != nil {\n    if errors.Is(err, av.ErrInvalidAttributeViewContextFilter) { logInvalidFilter(data, err) } else { return err }\n}","preventionTips":["Validate JSON payloads with a strict schema before persisting them into attributes","Avoid adding new fields without bumping spec","Store filters as single-line canonical JSON to reduce corruption"],"tags":["json","parsing","context-filter"],"backgroundTag":"json-decode-failed","analyzedSha":"8641553a1f07374001902d3ce773285db1292b2d","analyzedAt":"2026-09-11T16:08:28.414Z","contentChangedAt":"2026-09-11T16:08:28.414Z","schemaVersion":2},"datasetVersion":"2026-09-14T00:17:10.932Z"}