siyuan-note/siyuan · error
invalid tabs position [%s]
Error message
invalid tabs position [%s]
What it means
When the tabs-position attribute is present on a tab container, ValidateTabsAttrs requires its trimmed value to be exactly "top" or "left". Any other string (after trimming whitespace and removing invalid control characters) is rejected with this error.
Source
Thrown at kernel/treenode/tabs.go:57
}
// ValidateTabsAttrs 在修改属性前校验页签属性,避免部分属性已写入后才发现错误。
func ValidateTabsAttrs(node *ast.Node, attrs map[string]string) error {
for name, value := range attrs {
name = strings.ToLower(name)
if TabsActiveIDAttr != name && TabsPositionAttr != name {
continue
}
if nil == node || ast.NodeTabs != node.Type {
return fmt.Errorf("attribute [%s] is only supported on tab containers", name)
}
value = strings.TrimSpace(util.RemoveInvalidRetainCtrl(value))
if "" == value {
continue
}
if TabsPositionAttr == name {
if "top" != value && "left" != value {
return fmt.Errorf("invalid tabs position [%s]", value)
}
continue
}
found := false
for item := node.FirstChild; nil != item; item = item.Next {
if ast.NodeTabItem == item.Type && item.ID == value {
found = true
break
}
}
if !found {
return fmt.Errorf("active tab [%s] is not a direct child of [%s]", value, node.ID)
}
}
return nil
}
// NormalizeTabs 修复空页和无效选中项,保留所有已有内容及块标识。View on GitHub (pinned to 8641553a1f)
Solutions
- Set the value to exactly "top" or "left" (lowercase, no extra whitespace)
- Validate/normalize user input in the plugin before calling setNodeAttrs
- Omit the attribute entirely to keep the default position
Example fix
// before
setNodeAttrs(tabsID, { "tabs-position": "Bottom" });
// after
const pos = value.trim().toLowerCase();
if (pos === "top" || pos === "left") {
setNodeAttrs(tabsID, { "tabs-position": pos });
} Defensive patterns
Strategy: validation
Validate before calling
const VALID = ["top", "left"];
const pos = String(value ?? "").trim().toLowerCase();
if (!VALID.includes(pos)) {
throw new Error(`tabs-position must be "top" or "left", got ${value}`);
} Prevention
- Whitelist positions in plugin settings UI instead of free text
- Normalize case/whitespace before calling setNodeAttrs
- Remember only "top" and "left" exist — no right/bottom
When it happens
Trigger: Setting tabs-position on a NodeTabs node via setNodeAttrs0 with a value other than "top"/"left" — e.g. "right", "bottom", "Top", "top ". with a non-breaking space, or an empty-but-nonblank leftover string.
Common situations: Hand-written plugin config offering more orientations than supported; case-sensitivity mistakes; copying values from CSS-like configs that allow "bottom"/"right".
Understand the failure class
Background: Invalid enum value errors: "Unknown type", "Invalid scope", "must be one of" — when a string is not on the library's allowed list — this error's family across 23 libraries.
Related errors
- attribute [%s] is only supported on tab containers
- active tab [%s] is not a direct child of [%s]
- data?.msg || data?.message || window.siyuan.languages._kerne
- wrong layout type
- filter nesting depth exceeds the maximum allowed
AI-assisted analysis of siyuan-note/siyuan@8641553a1f (2026-09-11).
Data as JSON: /api/errors/2a0adfb5712cd9c9.
Report an issue: GitHub.