siyuan-note/siyuan · error
attribute view [%s] is not bound
Error message
attribute view [%s] is not bound
What it means
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.
Source
Thrown at kernel/model/attribute_view.go:8619
}
return
}
func sortAttrViewBindingIDs(avIDs []string, avID, previousAvID string) (ret []string, err error) {
ret = append([]string(nil), avIDs...)
if avID == previousAvID {
return
}
index := -1
for i, id := range ret {
if id == avID {
index = i
break
}
}
if 0 > index {
return nil, fmt.Errorf("attribute view [%s] is not bound", avID)
}
ret = append(ret[:index], ret[index+1:]...)
previousIndex := -1
if "" != previousAvID {
for i, id := range ret {
if id == previousAvID {
previousIndex = i
break
}
}
if 0 > previousIndex {
return nil, fmt.Errorf("previous attribute view [%s] is not bound", previousAvID)
}
}
ret = util.InsertElem(ret, previousIndex+1, avID)
returnView on GitHub (pinned to 8641553a1f)
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)
Example fix
// before
unbindAttrView(blockID, avID)
// after
if getBoundAvIDs(blockID).includes(avID) { unbindAttrView(blockID, avID) } Defensive patterns
Strategy: validation
Validate before calling
const ids = await getBoundAvIDs(blockID); if (!ids.includes(avID)) throw new Error("view not bound: " + avID); Type guard
const isBound = (ids, avID) => Array.isArray(ids) && ids.includes(avID);
Try / catch
try { await unbind(avID); } catch (e) { if (String(e).includes("is not bound")) return; throw e; } Prevention
- Make unbind idempotent in callers
- Refresh bound-view lists before reorder operations
- Do not cache avIDs across view deletions
When it happens
Trigger: Calling the unbind/reorder attribute view API with an avID that is not in the block's bound-view list (index stays -1).
Common situations: 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.
Understand the failure class
Background: "Not found" and "does not exist" errors: why "Task not found", "No such folder", and "Can't find" fire when a lookup comes back empty — this error's family across 14 libraries.
Related errors
- previous attribute view [%s] is not bound
- view [%s] not found in attribute view [%s]
- attribute view not found
- invalid attribute view id
- view not found
AI-assisted analysis of siyuan-note/siyuan@8641553a1f (2026-09-11).
Data as JSON: /api/errors/7cf78ebcaaa6507e.
Report an issue: GitHub.