{"record":{"id":"6683fa34f3943804","repo":"siyuan-note/siyuan","slug":"createdoctree-document-template-and-define-are-mut","errorCode":null,"errorMessage":"createDocTree document template and define are mutually exclusive","messagePattern":"createDocTree document template and define are mutually exclusive","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"kernel/model/template_doc_tree.go","lineNumber":172,"sourceCode":"\t\t}\n\t\ttitle = normalizeDocTitle(title)\n\t\tif \"\" == title {\n\t\t\treturn nil, errors.New(\"createDocTree document title must not be empty\")\n\t\t}\n\t\tif 512 < utf8.RuneCountInString(title) {\n\t\t\treturn nil, fmt.Errorf(\"createDocTree document title exceeds %d characters\", 512)\n\t\t}\n\n\t\ttemplateName, err := templateDocTreeStringField(definition, \"template\")\n\t\tif nil != err {\n\t\t\treturn nil, err\n\t\t}\n\t\tdefineName, err := templateDocTreeStringField(definition, \"define\")\n\t\tif nil != err {\n\t\t\treturn nil, err\n\t\t}\n\t\tif \"\" != templateName && \"\" != defineName {\n\t\t\treturn nil, errors.New(\"createDocTree document template and define are mutually exclusive\")\n\t\t}\n\n\t\tstate.count++\n\t\tif maxTemplateDocTreeDocs < state.count {\n\t\t\treturn nil, fmt.Errorf(\"createDocTree exceeds the maximum document count of %d\", maxTemplateDocTreeDocs)\n\t\t}\n\t\tid := ast.NewNodeID()\n\t\tnode := &TemplateDocTreeNode{\n\t\t\tID:       id,\n\t\t\tRootID:   id,\n\t\t\tTitle:    title,\n\t\t\tDepth:    depth,\n\t\t\tTemplate: templateName,\n\t\t\tDefine:   defineName,\n\t\t}\n\t\tif childrenValue, exists := definition[\"children\"]; exists {\n\t\t\tchildren, parseErr := state.parseNodes(childrenValue, depth+1)\n\t\t\tif nil != parseErr {","sourceCodeStart":154,"sourceCodeEnd":190,"githubUrl":"https://github.com/siyuan-note/siyuan/blob/9f775e8a12daef8255556097396f9b2739078892/kernel/model/template_doc_tree.go#L154-L190","documentation":"A createDocTree document may specify either a template file (template) or a template definition (define), never both. If templateDocTreeStringField returns non-empty values for both keys, parseNodes rejects the entry because the two content sources would conflict.","triggerScenarios":"A document object containing both non-empty \"template\" and \"define\" fields, e.g. {\"title\": \"Doc\", \"template\": \"a.md\", \"define\": \"b\"}. Raised from parseTemplateDocTreeDefinition during editor template insertion.","commonSituations":"Merging two template snippets that each used one of the fields; leaving a default define value in place while adding a template reference; refactoring templates from one mechanism to the other without removing the old key.","solutions":["Remove the \"define\" field and keep only \"template\" (or vice versa).","Decide which content source the document should use and delete the other key.","Search templates for entries that set both fields and clean them up."],"exampleFix":"// before\n{\"title\": \"Doc\", \"template\": \"a.md\", \"define\": \"b\"}\n// after\n{\"title\": \"Doc\", \"template\": \"a.md\"}","handlingStrategy":"validation","validationCode":"const exclusive = (d) => !(d.template && d.define);\nif (!docs.every(exclusive)) throw new Error('template and define are mutually exclusive');","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Decide on one content-source mechanism per document and use only that key.","Delete leftover define/template keys when converting templates.","Validate the mutual-exclusion invariant in generators."],"tags":["template","validation","conflict"],"backgroundTag":"mutually-exclusive-options","analyzedSha":"9f775e8a12daef8255556097396f9b2739078892","analyzedAt":"2026-09-19T03:17:15.984Z","contentChangedAt":"2026-09-19T03:17:15.984Z","schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}