siyuan-note/siyuan · error

invalid create attribute view item documents save mode

Error message

invalid create attribute view item documents save mode [%s]

What it means

attributeViewItemDocumentTemplate only accepts two save modes for CreateAttributeViewItemDocs: "subDoc" (CreateAttributeViewItemDocsSaveModeSubDoc) and "template" (CreateAttributeViewItemDocsSaveModeTemplate). Any other saveMode string hits the default branch and returns this error. It is a strict enum validation on the API parameter.

Solutions

  1. Pass exactly "subDoc" or "template" (prefer the exported constants model.CreateAttributeViewItemDocsSaveModeSubDoc / CreateAttributeViewItemDocsSaveModeTemplate)
  2. Check the client payload/casing; the comparison is case-sensitive
  3. If a default is desired, choose "template" explicitly, which falls back to the database's default document template

Example fix

// before
res, err := model.CreateAttributeViewItemDocs(avID, blockID, "document", itemIDs)
// after
res, err := model.CreateAttributeViewItemDocs(avID, blockID, model.CreateAttributeViewItemDocsSaveModeSubDoc, itemIDs)
Defensive patterns

Strategy: validation

Validate before calling

const validModes = map[string]bool{"subDoc": true, "template": true}
if !validModes[saveMode] { return fmt.Errorf("unsupported saveMode %q", saveMode) }

Prevention

When it happens

Trigger: Calling CreateAttributeViewItemDocs (API /api/attr/createAttributeViewItemDocs) with saveMode set to "", "doc", "SubDoc", or any value other than exactly "subDoc" or "template".

Common situations: Client code hard-coding a mode string instead of the exported constants; casing mistakes; older clients sending a mode name that was renamed when the feature was introduced.

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


AI-assisted analysis of siyuan-note/siyuan@9f775e8a12 (2026-09-19). Data as JSON: /api/errors/3ca0917a2d06edc0. Report an issue: GitHub.

Appendix: source

Thrown at kernel/model/attribute_view_new_item.go:368

	lock.Lock()
	return lock.Unlock
}

func attributeViewItemDocumentTemplate(attrView *av.AttributeView, saveMode string) (*av.NewItemTemplate, error) {
	switch saveMode {
	case CreateAttributeViewItemDocsSaveModeSubDoc:
		return &av.NewItemTemplate{
			TargetType:   av.NewItemTargetDocument,
			SaveLocation: &av.NewItemSaveLocation{},
		}, nil
	case CreateAttributeViewItemDocsSaveModeTemplate:
		itemTemplate := attrView.GetNewItemTemplate(attrView.DefaultTemplateID)
		if nil != itemTemplate && av.NewItemTargetDocument == itemTemplate.TargetType {
			return itemTemplate, nil
		}
		return &av.NewItemTemplate{TargetType: av.NewItemTargetDocument}, nil
	default:
		return nil, fmt.Errorf("invalid create attribute view item documents save mode [%s]", saveMode)
	}
}

func resolveAttributeViewNewItemTemplate(blockID string, itemTemplate *av.NewItemTemplate, createdAt time.Time) (*NewItemTemplatePreview, error) {
	return resolveAttributeViewNewItemTemplateWithFallback(blockID, itemTemplate, createdAt, "")
}

func resolveAttributeViewNewItemTemplateWithFallback(blockID string, itemTemplate *av.NewItemTemplate, createdAt time.Time,
	primaryFallback string) (*NewItemTemplatePreview, error) {
	boxID := ""
	if blockTree := treenode.GetBlockTree(blockID); blockTree != nil {
		boxID = blockTree.BoxID
	} else {
		for _, encBoxID := range treenode.GetOpenedEncryptedBoxIDs() {
			if blockTree := treenode.GetBlockTreeInBox(blockID, encBoxID); blockTree != nil {
				boxID = encBoxID
				break
			}

View on GitHub (pinned to 9f775e8a12)