siyuan-note/siyuan · error
previous ID and next ID cannot both be specified
Error message
previous ID and next ID cannot both be specified
What it means
A new database block can be appended to a parent, or inserted relative to one sibling (before previousID or after nextID), but not positioned between two siblings simultaneously. Supplying both previousID and nextID is ambiguous, so the function rejects the call.
Source
Thrown at kernel/model/attribute_view_create.go:55
Icon string `json:"icon,omitempty"`
}
// AttributeViewCreateResult 描述创建数据库后可供调用方继续操作的标识和数据。
type AttributeViewCreateResult struct {
BlockID string
AvID string
ViewID string
AttributeView *av.AttributeView
}
// CreateAttributeViewDatabase 创建数据库块和对应属性视图,并按照 keySpecs 的顺序初始化字段。
func CreateAttributeViewDatabase(parentID, previousID, nextID, name, primaryKeyName string, layout av.LayoutType,
keySpecs []*AttributeViewCreateKey) (ret *AttributeViewCreateResult, err error) {
if "" == parentID {
return nil, errors.New("parent ID is required")
}
if "" != previousID && "" != nextID {
return nil, errors.New("previous ID and next ID cannot both be specified")
}
if "" == previousID && "" == nextID {
if err = treenode.CheckContainerParent(parentID); nil != err {
return nil, err
}
}
if "" == layout {
layout = av.LayoutTypeTable
}
switch layout {
case av.LayoutTypeTable, av.LayoutTypeGallery, av.LayoutTypeKanban:
default:
return nil, av.ErrWrongLayoutType
}
preparedKeys := make([]*av.Key, 0, len(keySpecs))
for _, spec := range keySpecs {
if nil == spec || "" == strings.TrimSpace(spec.Name) || "" == strings.TrimSpace(spec.Type) {View on GitHub (pinned to 8641553a1f)
Solutions
- Pass only one of previousID or nextID, leaving the other as ""
- If you truly need to insert between two blocks, pass the left neighbor as previousID and empty nextID (or the right neighbor as nextID)
- Add caller-side logic that clears the opposite field when one anchor is chosen
Example fix
// before
ret, err := model.CreateAttributeViewDatabase(parentID, prevID, nextID, name, pk, layout, keys)
// after
if prevID != "" {
nextID = "" // only one sibling anchor is allowed
}
ret, err := model.CreateAttributeViewDatabase(parentID, prevID, nextID, name, pk, layout, keys) Defensive patterns
Strategy: validation
Validate before calling
if previousID != "" && nextID != "" {
return errors.New("specify only one of previousID or nextID")
} Prevention
- Model insertion as {append | after prev | before next} and clear the unused anchor field
- Never forward raw multi-field UI selection state into the API without narrowing it
- Write a small normalizeInsertion helper used by all call sites
When it happens
Trigger: Calling CreateAttributeViewDatabase with both previousID and nextID set to non-empty values.
Common situations: A caller that forwards UI selection state (which may contain both anchor directions) directly into the API; code that builds insertion options from a struct with optional fields but forgets to clear the unused sibling.
Related errors
- parent ID is required
- wrong layout type
- filter nesting depth exceeds the maximum allowed
- new item template name is empty
- invalid new item template id [%s]
AI-assisted analysis of siyuan-note/siyuan@8641553a1f (2026-09-11).
Data as JSON: /api/errors/f2c729ff7f74a0d8.
Report an issue: GitHub.