{"record":{"id":"21623abded13767c","repo":"siyuan-note/siyuan","slug":"invalid-filter-target-field-s","errorCode":null,"errorMessage":"invalid filter target field: %s","messagePattern":"invalid filter target field: (.+?)","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"kernel/model/attribute_view_key_config.go","lineNumber":171,"sourceCode":"\t}\n\tif err = av.ValidateFilterDepth(filters); nil != err {\n\t\treturn err\n\t}\n\tvar validate func([]*av.ViewFilter) error\n\tvalidate = func(items []*av.ViewFilter) error {\n\t\tfor _, filter := range items {\n\t\t\tif nil == filter {\n\t\t\t\treturn errors.New(\"filter must not be null\")\n\t\t\t}\n\t\t\tif filter.IsGroup() {\n\t\t\t\tif av.FilterCombinationAnd != filter.Combination && av.FilterCombinationOr != filter.Combination {\n\t\t\t\t\treturn errors.New(\"filter group requires and/or combination\")\n\t\t\t\t}\n\t\t\t\tif err := validate(filter.Filters); nil != err {\n\t\t\t\t\treturn err\n\t\t\t\t}\n\t\t\t} else if _, err := dest.GetKey(filter.Column); nil != err {\n\t\t\t\treturn fmt.Errorf(\"invalid filter target field: %s\", filter.Column)\n\t\t\t}\n\t\t}\n\t\treturn nil\n\t}\n\treturn validate(filters)\n}\n\n// decodeAttributeViewKeyConfig 拒绝未知字段及空值，防止拼写错误被当作成功更新。\nfunc decodeAttributeViewKeyConfig(value, dest any) error {\n\tif nil == value {\n\t\treturn errors.New(\"configuration must not be null\")\n\t}\n\tdata, err := json.Marshal(value)\n\tif nil != err {\n\t\treturn err\n\t}\n\tdecoder := json.NewDecoder(bytes.NewReader(data))\n\tdecoder.DisallowUnknownFields()","sourceCodeStart":153,"sourceCodeEnd":189,"githubUrl":"https://github.com/siyuan-note/siyuan/blob/9f775e8a12daef8255556097396f9b2739078892/kernel/model/attribute_view_key_config.go#L153-L189","documentation":"This error is thrown when a non-group filter targets filter.Column (a field/key ID) that does not exist in the target attribute view being filtered. Validation resolves the relation's target view via GetKey and rejects references to deleted or foreign field IDs so stored filters never dangle.","triggerScenarios":"Setting 'filters' or 'rollupFilters' via UpdateAttributeViewKeyConfig with a filter whose column/key ID is not a field of the relation's target view: deleted field, ID copied from the wrong view, or truncated/typo'd ID.","commonSituations":"Plugin built filter payloads against an older schema of the target view; the target field was removed by another user before the filter was saved; developer confused the view's own key ID with the related view's key ID.","solutions":["Fetch the target view's keys (attrView.GetKey / view listing) and use one of those key IDs in filter.Column","Regenerate the filter payload from the current schema of the related view","Verify the relation field's AvID matches the view you took the column ID from"],"exampleFix":"// before\n{\"column\":\"20230101120000-stale\",\"value\":{\"content\":\"todo\"}}\n// after\n{\"column\":\"20240101120000-current\",\"value\":{\"content\":\"todo\"}}","handlingStrategy":"validation","validationCode":"const targetKeys = new Set((await getAvKeys(relationAvID)).map(k => k.id));\nfor (const f of filters) {\n  if (!f.filters?.length && !targetKeys.has(f.column)) {\n    throw new Error(`unknown filter column ${f.column}`);\n  }\n}","typeGuard":null,"tryCatchPattern":"try { await setFilters(); } catch (e) { if (String(e).includes(\"invalid filter target field\")) await refreshSchemaAndRetry(); }","preventionTips":["Derive filter column IDs from a fresh fetch of the related view, never from cached schema","Re-validate filters after any field deletion in the related view"],"tags":["attribute-view","filter","foreign-key"],"backgroundTag":"entity-not-found","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"}