{"record":{"id":"7cf78ebcaaa6507e","repo":"siyuan-note/siyuan","slug":"attribute-view-s-is-not-bound","errorCode":null,"errorMessage":"attribute view [%s] is not bound","messagePattern":"attribute view \\[(.+?)\\] is not bound","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"kernel/model/attribute_view.go","lineNumber":8619,"sourceCode":"\t}\n\treturn\n}\n\nfunc sortAttrViewBindingIDs(avIDs []string, avID, previousAvID string) (ret []string, err error) {\n\tret = append([]string(nil), avIDs...)\n\tif avID == previousAvID {\n\t\treturn\n\t}\n\n\tindex := -1\n\tfor i, id := range ret {\n\t\tif id == avID {\n\t\t\tindex = i\n\t\t\tbreak\n\t\t}\n\t}\n\tif 0 > index {\n\t\treturn nil, fmt.Errorf(\"attribute view [%s] is not bound\", avID)\n\t}\n\n\tret = append(ret[:index], ret[index+1:]...)\n\tpreviousIndex := -1\n\tif \"\" != previousAvID {\n\t\tfor i, id := range ret {\n\t\t\tif id == previousAvID {\n\t\t\t\tpreviousIndex = i\n\t\t\t\tbreak\n\t\t\t}\n\t\t}\n\t\tif 0 > previousIndex {\n\t\t\treturn nil, fmt.Errorf(\"previous attribute view [%s] is not bound\", previousAvID)\n\t\t}\n\t}\n\n\tret = util.InsertElem(ret, previousIndex+1, avID)\n\treturn","sourceCodeStart":8601,"sourceCodeEnd":8637,"githubUrl":"https://github.com/siyuan-note/siyuan/blob/8641553a1f07374001902d3ce773285db1292b2d/kernel/model/attribute_view.go#L8601-L8637","documentation":"When reordering the embedded attribute views of a block, the kernel locates the current position of avID in the bound-view ID list; if it is absent the unbind/reorder cannot proceed and this error is returned.","triggerScenarios":"Calling the unbind/reorder attribute view API with an avID that is not in the block's bound-view list (index stays -1).","commonSituations":"Double unbind of the same view; an avID from a deleted view block; plugin caches a view ID after the view was removed; copy/pasted avID from another block.","solutions":["Check the block's bound attribute view IDs before calling unbind/reorder","Use the correct avID for the block being modified","Skip unbind if the view was already unbound (make the call idempotent in the caller)"],"exampleFix":"// before\nunbindAttrView(blockID, avID)\n// after\nif getBoundAvIDs(blockID).includes(avID) { unbindAttrView(blockID, avID) }","handlingStrategy":"validation","validationCode":"const ids = await getBoundAvIDs(blockID); if (!ids.includes(avID)) throw new Error(\"view not bound: \" + avID);","typeGuard":"const isBound = (ids, avID) => Array.isArray(ids) && ids.includes(avID);","tryCatchPattern":"try { await unbind(avID); } catch (e) { if (String(e).includes(\"is not bound\")) return; throw e; }","preventionTips":["Make unbind idempotent in callers","Refresh bound-view lists before reorder operations","Do not cache avIDs across view deletions"],"tags":["attribute-view","not-bound","entity-not-found"],"backgroundTag":"entity-not-found","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"}