{"record":{"id":"c9e692fff7c7a441","repo":"siyuan-note/siyuan","slug":"invalid-path","errorCode":null,"errorMessage":"invalid path","messagePattern":"invalid path","errorType":"error_code","errorClass":null,"httpStatus":null,"severity":"error","filePath":"kernel/filesys/tree.go","lineNumber":248,"sourceCode":"\ttreenode.UpgradeSpec(tree)\n\tescapeAttributeValues(tree)\n\treturn\n}\n\nfunc LoadTreeByData(data []byte, boxID, p string, luteEngine *lute.Lute) (ret *parse.Tree, err error) {\n\tret, err = parseJSON2Tree(boxID, p, data, luteEngine)\n\tif nil != err {\n\t\tlogging.LogErrorf(\"parse tree [%s] failed: %s\", p, err)\n\t\treturn\n\t}\n\tret.Path = p\n\tret.Root.Path = p\n\n\thPath := \"/\" + strings.TrimPrefix(filepath.ToSlash(p), \"/\")\n\tparts := strings.Split(hPath, \"/\")\n\tif len(parts) < 2 {\n\t\tlogging.LogErrorf(\"parse tree [%s] failed: invalid path\", p)\n\t\terr = errors.New(\"invalid path\")\n\t\treturn\n\t}\n\n\tparts = parts[1 : len(parts)-1] // 去掉开头的斜杆和结尾的自己\n\tif 1 > len(parts) {\n\t\tret.HPath = \"/\" + ret.Root.IALAttr(\"title\")\n\t\tret.Hash = treenode.NodeHash(ret.Root, ret, luteEngine)\n\t\treturn\n\t}\n\n\t// 构造 HPath\n\thPathBuilder := bytes.Buffer{}\n\thPathBuilder.WriteString(\"/\")\n\tfor i := range parts {\n\t\tvar parentAbsPath string\n\t\tif 0 < i {\n\t\t\tparentAbsPath = strings.Join(parts[:i+1], \"/\")\n\t\t} else {","sourceCodeStart":230,"sourceCodeEnd":266,"githubUrl":"https://github.com/siyuan-note/siyuan/blob/251596fc0de2f9528c00c224252fd073a99973f4/kernel/filesys/tree.go#L230-L266","documentation":"Returned by `filesys.LoadTreeByData` when, after splitting the hPath on `/`, the result has fewer than two parts. A valid SiYuan document path must contain at least a leading slash plus the document's own segment, so `len(parts) < 2` indicates a malformed path that cannot yield a meaningful hPath.","triggerScenarios":"Parsing a tree whose `p` is empty, a bare `/`, or otherwise lacks the `/<something>/` shape expected of a doc path inside a notebook.","commonSituations":"Tree data loaded with an empty or `\"/\"` path; programmatic construction of `LoadTreeByData` with a placeholder path; import logic that did not set the document path correctly.","solutions":["Ensure `p` is a full box-relative doc path like `20240101000000-abcdef1234567/sub.sy`.","If generating paths, build them from the parent dir plus the root-ID-based filename.","Validate the path shape (`strings.Split` yields >= 2 parts) before calling `LoadTreeByData`."],"exampleFix":"// before\ntree, err := filesys.LoadTreeByData(data, box, \"/\", lute)\n// after\ntree, err := filesys.LoadTreeByData(data, box, \"20240101000000-abcdef1234567/page.sy\", lute)","handlingStrategy":"validation","validationCode":"// Validate the path shape before loading by data:\nparts := strings.Split(filepath.ToSlash(p), \"/\")\nif len(parts) < 2 {\n    return errors.New(\"invalid path\")\n}","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Build doc paths from parent dir + root-ID filename, never from empty placeholders.","Validate path shape at the trust boundary before reaching filesys internals.","Unit-test LoadTreeByData with realistic notebook paths."],"tags":["validation","path","tree"],"backgroundTag":null,"analyzedSha":"251596fc0de2f9528c00c224252fd073a99973f4","analyzedAt":"2026-08-12T21:18:37.123Z","schemaVersion":2},"datasetVersion":"2026-08-12T23:17:12.415Z"}