{"record":{"id":"4412b8a0e5655169","repo":"siyuan-note/siyuan","slug":"createdoctree-document-title-must-not-be-empty","errorCode":null,"errorMessage":"createDocTree document title must not be empty","messagePattern":"createDocTree document title must not be empty","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"kernel/model/template_doc_tree.go","lineNumber":157,"sourceCode":"\t\tfor key := range definition {\n\t\t\tswitch key {\n\t\t\tcase \"title\", \"template\", \"define\", \"children\":\n\t\t\tdefault:\n\t\t\t\treturn nil, fmt.Errorf(\"createDocTree document contains unknown field [%s]\", key)\n\t\t\t}\n\t\t}\n\n\t\ttitleValue, ok := definition[\"title\"]\n\t\tif !ok {\n\t\t\treturn nil, errors.New(\"createDocTree document title is required\")\n\t\t}\n\t\ttitle, ok := titleValue.(string)\n\t\tif !ok {\n\t\t\treturn nil, errors.New(\"createDocTree document title must be a string\")\n\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++","sourceCodeStart":139,"sourceCodeEnd":175,"githubUrl":"https://github.com/siyuan-note/siyuan/blob/8641553a1f07374001902d3ce773285db1292b2d/kernel/model/template_doc_tree.go#L139-L175","documentation":"After normalization (normalizeDocTitle trims whitespace and strips invalid characters), a title that normalizes to the empty string is rejected. Titles become file-system path segments for the new documents, so an empty title cannot produce a valid document path.","triggerScenarios":"A title of \"\" or only whitespace (\" \"); a title made entirely of characters removed by normalizeDocTitle (e.g. path separators or illegal filename characters); interpolation that yields an empty string at render time.","commonSituations":"Template placeholders like {{.Name}} that resolve to empty; authors using only slashes or dots in titles; data-driven generation where the source field is empty.","solutions":["Provide a non-empty title containing at least one valid character.","Check that any template-variable interpolation in the title produces non-empty text at render time.","Strip or replace characters that normalize away (/, \\, control chars) with readable substitutes before rendering.","Pre-validate titles: trim and reject empty/whitespace-only strings before invoking createDocTree."],"exampleFix":"// before\n{\"title\": \"   \"}\n// after\n{\"title\": \"Untitled\"}","handlingStrategy":"validation","validationCode":"var walk func(nodes []any) error\nwalk = func(nodes []any) error {\n    for _, v := range nodes {\n        m, ok := v.(map[string]any)\n        if !ok { continue }\n        if t, ok := m[\"title\"].(string); ok {\n            if strings.TrimSpace(t) == \"\" {\n                return errors.New(\"title must not be empty or whitespace\")\n            }\n        }\n        if c, ok := m[\"children\"]; ok {\n            if cl, ok := c.([]any); ok {\n                if err := walk(cl); err != nil { return err }\n            }\n        }\n    }\n    return nil\n}","typeGuard":"func hasNonEmptyTitle(v any) bool {\n    m, ok := v.(map[string]any)\n    if !ok { return false }\n    t, ok := m[\"title\"].(string)\n    return ok && strings.TrimSpace(t) != \"\"\n}","tryCatchPattern":"nodes, err := parseTemplateDocTreeDefinition(def)\nif err != nil {\n    if strings.Contains(err.Error(), \"title must not be empty\") {\n        // substitute a default title and retry\n    }\n    return err\n}","preventionTips":["Check that template-variable interpolation in titles resolves to non-empty text.","Avoid titles made only of characters stripped by normalization (slashes, whitespace, control chars).","Provide a fallback default title for empty source fields in generators."],"tags":["template","empty-input","title"],"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"}