{"record":{"id":"23a9f7bf16bcb788","repo":"siyuan-note/siyuan","slug":"createdoctree-document-s-must-not-be-empty","errorCode":null,"errorMessage":"createDocTree document %s must not be empty","messagePattern":"createDocTree document (.+?) must not be empty","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"kernel/model/template_doc_tree.go","lineNumber":211,"sourceCode":"\t\t\tnode.Children = children\n\t\t}\n\t\tnodes = append(nodes, node)\n\t}\n\treturn nodes, nil\n}\n\nfunc templateDocTreeStringField(definition map[string]any, key string) (string, error) {\n\tvalue, exists := definition[key]\n\tif !exists {\n\t\treturn \"\", nil\n\t}\n\tret, ok := value.(string)\n\tif !ok {\n\t\treturn \"\", fmt.Errorf(\"createDocTree document %s must be a string\", key)\n\t}\n\tret = strings.TrimSpace(ret)\n\tif \"\" == ret {\n\t\treturn \"\", fmt.Errorf(\"createDocTree document %s must not be empty\", key)\n\t}\n\treturn ret, nil\n}\n\nfunc (collector *templateDocTreeCollector) create(def any) (string, error) {\n\tif !collector.enabled || !collector.allowCreation {\n\t\treturn \"\", errors.New(\"createDocTree is only available when manually inserting a template in the editor\")\n\t}\n\tnodes, err := parseTemplateDocTreeDefinition(def)\n\tif nil != err {\n\t\treturn \"\", err\n\t}\n\tif maxTemplateDocTreeDocs < len(flattenTemplateDocTreeNodes0(collector.nodes))+len(flattenTemplateDocTreeNodes0(nodes)) {\n\t\treturn \"\", fmt.Errorf(\"createDocTree exceeds the maximum document count of %d\", maxTemplateDocTreeDocs)\n\t}\n\tcollector.bindNodes(nodes, collector.rootID, collector.rootPath, collector.rootHPath)\n\tcollector.nodes = append(collector.nodes, nodes...)\n\treturn \"\", nil","sourceCodeStart":193,"sourceCodeEnd":229,"githubUrl":"https://github.com/siyuan-note/siyuan/blob/8641553a1f07374001902d3ce773285db1292b2d/kernel/model/template_doc_tree.go#L193-L229","documentation":"After confirming the \"template\" or \"define\" field is a string, the parser trims whitespace and rejects it if the result is empty. A key present with an empty or whitespace-only string value is treated as invalid rather than as absent, so createDocTree parsing fails with \"createDocTree document <key> must not be empty\".","triggerScenarios":"A createDocTree document entry such as {\"title\":\"x\",\"template\":\"\"}, {\"title\":\"x\",\"define\":\"   \"}, or a value built by string concatenation/interpolation that resolved to empty.","commonSituations":"Template variables that expanded to nothing (e.g. .\"\" . $name with an unset variable), copy-pasted entries with the value deleted, or form-generated JSON where empty inputs were serialized as \"\" instead of omitted.","solutions":["Provide a real template/define name, or delete the key entirely when it is not needed.","If the value comes from a variable, guard it: only emit the field when the variable is non-empty.","Trim inputs before building the definition and omit empty fields."],"exampleFix":"// before\n{\"title\":\"Child\",\"define\":\"\"}\n// after\n{\"title\":\"Child\",\"define\":\"my-define\"}  // or remove the define key","handlingStrategy":"validation","validationCode":"for (const doc of definition) {\n  for (const key of [\"template\", \"define\"]) {\n    if (key in doc && typeof doc[key] === \"string\" && doc[key].trim() === \"\") throw new Error(`${key} must not be empty`);\n  }\n}","typeGuard":"const hasValue = (v) => typeof v === \"string\" && v.trim().length > 0;","tryCatchPattern":"try {\n  render(def);\n} catch (e) {\n  if (/must not be empty/.test(String(e))) {\n    // remove the empty key or supply a real value\n  }\n}","preventionTips":["Delete optional keys rather than leaving them empty","Guard template variables so empty expansions omit the field","Trim and filter empty strings when building definitions programmatically"],"tags":["template","empty-value","validation"],"backgroundTag":"empty-required-field","analyzedSha":"8641553a1f07374001902d3ce773285db1292b2d","analyzedAt":"2026-09-11T16:08:28.414Z","contentChangedAt":"2026-09-11T16:08:28.414Z","schemaVersion":2},"datasetVersion":"2026-09-14T00:17:10.932Z"}