{"record":{"id":"258982342a32c48c","repo":"siyuan-note/siyuan","slug":"new-item-templates-config-is-nil","errorCode":null,"errorMessage":"new item templates config is nil","messagePattern":"new item templates config is nil","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"kernel/av/new_item_template.go","lineNumber":40,"sourceCode":"\t\"sort\"\n\t\"strings\"\n\n\t\"github.com/88250/lute/ast\"\n\n\t\"github.com/siyuan-note/siyuan/kernel/util\"\n)\n\n// PrunedNewItemTemplateOption 描述创建条目前从模板字段值中移除的无效选项。\ntype PrunedNewItemTemplateOption struct {\n\tTemplateID string\n\tKeyID      string\n\tValues     []string\n}\n\n// SetNewItemTemplates 校验并替换数据库的新增条目模板配置。\nfunc (av *AttributeView) SetNewItemTemplates(config *NewItemTemplatesConfig) error {\n\tif nil == config {\n\t\treturn errors.New(\"new item templates config is nil\")\n\t}\n\n\ttemplates := make([]*NewItemTemplate, 0, len(config.Templates))\n\ttemplateIDs := map[string]bool{}\n\tdefaultTemplateID := config.DefaultTemplateID\n\tfor _, itemTemplate := range config.Templates {\n\t\tif nil == itemTemplate {\n\t\t\tcontinue\n\t\t}\n\t\titemTemplate = cloneNewItemTemplate(itemTemplate)\n\t\tif nil == itemTemplate {\n\t\t\treturn errors.New(\"clone new item template failed\")\n\t\t}\n\t\titemTemplate.Name = strings.TrimSpace(itemTemplate.Name)\n\t\titemTemplate.Icon = strings.TrimSpace(itemTemplate.Icon)\n\t\tif filteredIcon, valid := util.FilterIconValue(itemTemplate.Icon); valid {\n\t\t\titemTemplate.Icon = filteredIcon\n\t\t} else {","sourceCodeStart":22,"sourceCodeEnd":58,"githubUrl":"https://github.com/siyuan-note/siyuan/blob/251596fc0de2f9528c00c224252fd073a99973f4/kernel/av/new_item_template.go#L22-L58","documentation":"SetNewItemTemplates is the single entry point that validates and replaces an Attribute View's new-item template list; it refuses a nil config because every subsequent step dereferences config.Templates and config.DefaultTemplateID. The guard is the first line of defense before any allocation.","triggerScenarios":"Direct library call av.SetNewItemTemplates(nil), or a code path that constructs the config lazily and leaves it nil. The HTTP handler doSetAttrViewNewItemTemplates (model/attribute_view.go:5117) always allocates a non-nil *NewItemTemplatesConfig, so the API path does not normally hit this.","commonSituations":"SDK/plugin code calling SetNewItemTemplates without populating a config; a refactor that forgets to allocate the struct; tests that pass nil inadvertently.","solutions":["Pass a non-nil *NewItemTemplatesConfig; to clear templates, pass an empty struct (Templates nil/empty) — the function sets av.NewItemTemplates = nil for you (new_item_template.go:93).","If writing a handler, mirror doSetAttrViewNewItemTemplates: unmarshal into a freshly allocated config.","Add a nil-config check on the caller side and surface a clearer error before reaching the kernel."],"exampleFix":"// before\nav.SetNewItemTemplates(nil)\n// after\nav.SetNewItemTemplates(&av.NewItemTemplatesConfig{})","handlingStrategy":"type-guard","validationCode":null,"typeGuard":"func nonNilNewItemConfig(c *av.NewItemTemplatesConfig) (*av.NewItemTemplatesConfig, error) {\n    if c == nil {\n        return nil, errors.New(\"new item templates config is nil\")\n    }\n    return c, nil\n}","tryCatchPattern":"if err := attrView.SetNewItemTemplates(config); err != nil {\n    return &TxErr{code: TxErrHandleAttributeView, id: avID, msg: err.Error()}\n}","preventionTips":["Always allocate &av.NewItemTemplatesConfig{} before calling SetNewItemTemplates.","Mirror doSetAttrViewNewItemTemplates (model/attribute_view.go:5117) in your own handler.","To clear templates, pass an empty struct — do not pass nil."],"tags":["av","new-item-template","validation","nil-guard"],"backgroundTag":null,"analyzedSha":"251596fc0de2f9528c00c224252fd073a99973f4","analyzedAt":"2026-08-12T21:18:37.123Z","schemaVersion":2},"datasetVersion":"2026-08-12T23:17:12.415Z"}