siyuan-note/siyuan · error
createDocTree document %s must not be empty
Error message
createDocTree document %s must not be empty
What it means
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".
Source
Thrown at kernel/model/template_doc_tree.go:211
node.Children = children
}
nodes = append(nodes, node)
}
return nodes, nil
}
func templateDocTreeStringField(definition map[string]any, key string) (string, error) {
value, exists := definition[key]
if !exists {
return "", nil
}
ret, ok := value.(string)
if !ok {
return "", fmt.Errorf("createDocTree document %s must be a string", key)
}
ret = strings.TrimSpace(ret)
if "" == ret {
return "", fmt.Errorf("createDocTree document %s must not be empty", key)
}
return ret, nil
}
func (collector *templateDocTreeCollector) create(def any) (string, error) {
if !collector.enabled || !collector.allowCreation {
return "", errors.New("createDocTree is only available when manually inserting a template in the editor")
}
nodes, err := parseTemplateDocTreeDefinition(def)
if nil != err {
return "", err
}
if maxTemplateDocTreeDocs < len(flattenTemplateDocTreeNodes0(collector.nodes))+len(flattenTemplateDocTreeNodes0(nodes)) {
return "", fmt.Errorf("createDocTree exceeds the maximum document count of %d", maxTemplateDocTreeDocs)
}
collector.bindNodes(nodes, collector.rootID, collector.rootPath, collector.rootHPath)
collector.nodes = append(collector.nodes, nodes...)
return "", nilView on GitHub (pinned to 8641553a1f)
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.
Example fix
// before
{"title":"Child","define":""}
// after
{"title":"Child","define":"my-define"} // or remove the define key Defensive patterns
Strategy: validation
Validate before calling
for (const doc of definition) {
for (const key of ["template", "define"]) {
if (key in doc && typeof doc[key] === "string" && doc[key].trim() === "") throw new Error(`${key} must not be empty`);
}
} Type guard
const hasValue = (v) => typeof v === "string" && v.trim().length > 0;
Try / catch
try {
render(def);
} catch (e) {
if (/must not be empty/.test(String(e))) {
// remove the empty key or supply a real value
}
} Prevention
- 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
When it happens
Trigger: A createDocTree document entry such as {"title":"x","template":""}, {"title":"x","define":" "}, or a value built by string concatenation/interpolation that resolved to empty.
Common situations: 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.
Understand the failure class
Background: "must not be empty", "cannot be empty" — required-field validation errors across open-source libraries — this error's family across 41 libraries.
Related errors
- Tag cannot be empty
- block write failed: empty block ID
- path is required
- Conf.Language(126) (localized empty-bookmark-name message)
- inline style name must not be empty
AI-assisted analysis of siyuan-note/siyuan@8641553a1f (2026-09-11).
Data as JSON: /api/errors/23a9f7bf16bcb788.
Report an issue: GitHub.