{"record":{"id":"efdb81e505eab0b4","repo":"siyuan-note/siyuan","slug":"createdoctree-document-s-must-be-a-string","errorCode":null,"errorMessage":"createDocTree document %s must be a string","messagePattern":"createDocTree document (.+?) must be a string","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"kernel/model/template_doc_tree.go","lineNumber":207,"sourceCode":"\t\t\tchildren, parseErr := state.parseNodes(childrenValue, depth+1)\n\t\t\tif nil != parseErr {\n\t\t\t\treturn nil, parseErr\n\t\t\t}\n\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)","sourceCodeStart":189,"sourceCodeEnd":225,"githubUrl":"https://github.com/siyuan-note/siyuan/blob/9f775e8a12daef8255556097396f9b2739078892/kernel/model/template_doc_tree.go#L189-L225","documentation":"The optional template and define fields of a createDocTree document, when present, must be strings. templateDocTreeStringField (called for both keys from parseNodes) type-asserts the value and reports which key failed via the %s placeholder. The key names appear in the message, e.g. \"createDocTree document template must be a string\".","triggerScenarios":"Setting \"template\" or \"define\" to a non-string value such as a number, boolean, null, object, or list in a document object of a createDocTree definition.","commonSituations":"Generator code passing a parsed object under define instead of a name/id; JSON where the template reference was a list of files; null from an unresolved variable.","solutions":["Make the template/define value a string (e.g. a template file name or definition id).","If the value can be absent, remove the key entirely rather than setting null.","Validate field types in the generator before building the definition."],"exampleFix":"// before\n{\"title\": \"Doc\", \"define\": {\"content\": \"x\"}}\n// after\n{\"title\": \"Doc\", \"define\": \"my-define-id\"}","handlingStrategy":"type-guard","validationCode":"const validRef = (d) => d.template === undefined || typeof d.template === 'string';","typeGuard":"const isStringOrAbsent = (v) => v === undefined || typeof v === 'string';","tryCatchPattern":null,"preventionTips":["Keep template/define values as strings or omit the key.","Never serialize null for these fields.","Validate optional field types before building the definition."],"tags":["template","type-error","validation"],"backgroundTag":"type-mismatch","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"}