{"record":{"id":"1199b3e50a28852b","repo":"siyuan-note/siyuan","slug":"view-s-not-found-in-attribute-view-s","errorCode":null,"errorMessage":"view [%s] not found in attribute view [%s]","messagePattern":"view \\[(.+?)\\] not found in attribute view \\[(.+?)\\]","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"kernel/model/attribute_view.go","lineNumber":1252,"sourceCode":"\t}\n\treturn\n}\n\nfunc SetDatabaseBlockVisibleViews(blockID, avID string, viewIDs []string) (err error) {\n\tif 1 > len(viewIDs) {\n\t\treturn errors.New(\"at least one visible view is required\")\n\t}\n\n\tattrView, err := av.ParseAttributeView(avID)\n\tif nil != err {\n\t\tlogging.LogErrorf(\"parse attribute view [%s] failed: %s\", avID, err)\n\t\treturn\n\t}\n\n\tvisible := map[string]bool{}\n\tfor _, viewID := range viewIDs {\n\t\tif nil == attrView.GetView(viewID) {\n\t\t\treturn fmt.Errorf(\"view [%s] not found in attribute view [%s]\", viewID, avID)\n\t\t}\n\t\tvisible[viewID] = true\n\t}\n\n\tvar normalized []string\n\tfor _, view := range attrView.Views {\n\t\tif visible[view.ID] {\n\t\t\tnormalized = append(normalized, view.ID)\n\t\t}\n\t}\n\tif 1 > len(normalized) {\n\t\treturn errors.New(\"at least one visible view is required\")\n\t}\n\n\tnode, tree, err := getNodeByBlockID(nil, blockID)\n\tif nil != err {\n\t\treturn\n\t}","sourceCodeStart":1234,"sourceCodeEnd":1270,"githubUrl":"https://github.com/siyuan-note/siyuan/blob/251596fc0de2f9528c00c224252fd073a99973f4/kernel/model/attribute_view.go#L1234-L1270","documentation":"Returned by SetDatabaseBlockVisibleViews (attribute_view.go:1252) when one of the viewIDs passed to setAttrViewBlockVisibleViews does not resolve via attrView.GetView — i.e. the ID is not present in the attribute view's Views collection. The check runs before normalization, so a single bad ID aborts the whole call.","triggerScenarios":"Frontend sends a view ID that was deleted, belongs to a different attribute view, or is a stale/corrupted value carried over from an older avID. Duplicates are tolerated (they just set the map key twice), but any unknown ID fails.","commonSituations":"View was deleted in another mirror of the same database but the local UI list still shows it; plugin hard-codes a view ID; avID/viewID mismatch after a database was duplicated and IDs were not remapped.","solutions":["Refresh the view list from av.GetAttributeView before submitting and drop any ID no longer present.","Send only view IDs returned by a recent render of the same attribute view (operation.AvID must match).","If mirroring, confirm each view ID belongs to operation.AvID, not a sibling database."],"exampleFix":"// before: submitting a possibly stale id\ntransaction({ op: \"setAttrViewBlockVisibleViews\", avID, viewIDs: [\"20240101000000-old\"] })\n\n// after: filter against the live view list\nconst live = await fetchAttrView(avID)\nconst viewIDs = selected.filter(id => live.views.some(v => v.id === id))\nif (viewIDs.length) transaction({ op: \"setAttrViewBlockVisibleViews\", avID, viewIDs })","handlingStrategy":"validation","validationCode":"// Filter submitted viewIDs against the live attribute view before sending.\nconst live = await fetchAttrView(avID)\nconst valid = viewIDs.filter(id => live.views.some(v => v.id === id))\nif (valid.length !== viewIDs.length) throw new Error('one or more view IDs not found')","typeGuard":"function viewExists(av: AttributeView, id: string): boolean {\n  return av.views.some(v => v.id === id)\n}","tryCatchPattern":null,"preventionTips":["Re-fetch the attribute view before changing visible-view selection.","Ensure each viewID belongs to the same avID being targeted.","Drop deleted view IDs from the UI immediately after a view-delete transaction."],"tags":["attribute-view","av","database","view","validation","transaction"],"backgroundTag":null,"analyzedSha":"251596fc0de2f9528c00c224252fd073a99973f4","analyzedAt":"2026-08-12T21:18:37.123Z","schemaVersion":2},"datasetVersion":"2026-08-12T23:17:12.415Z"}