siyuan-note/siyuan · error

invalid path

Error message

invalid path

What it means

LoadTreeByData builds a tree from raw data and derives the hPath from the given relative path p. It splits the slash-normalized path and requires at least two segments (leading empty segment plus the document name). Fewer segments means the path is malformed (e.g. empty, "doc.sy" without a leading slash, or just "/"), so it fails with "invalid path".

Solutions

  1. Pass a proper notebook-relative path with a leading slash, e.g. "/doc.sy" or "/folder/doc.sy".
  2. Check the variable supplying p is populated before the call.
  3. Normalize the path with filepath.ToSlash and ensure it is not empty.

Example fix

// before
LoadTreeByData(boxID, "doc.sy", data, lute)
// after
LoadTreeByData(boxID, "/doc.sy", data, lute)
Defensive patterns

Strategy: validation

Validate before calling

function isValidDocPath(p) {
  const norm = "/" + String(p || "").replace(/^\/+/, "");
  return norm.split("/").length >= 2 && norm.length > 1;
}

Try / catch

if err := filesys.LoadTreeByData(boxID, p, data, lute); err != nil {
    // invalid or unparseable path; fix the path argument
}

Prevention

When it happens

Trigger: Calling LoadTreeByData with p == "", a bare file name like "doc.sy", or "/" — any path where strings.Split of "/"+trimmed p yields fewer than 2 parts.

Common situations: Passing a path missing its leading slash; a variable that was supposed to hold the document path left empty; callers constructing paths without the notebook-relative "/folder/doc.sy" form.

Understand the failure class

Background: "Invalid ... format", "must be in format X", "does not look like a ..." — invalid argument format errors across CLI tools and libraries — this error's family across 17 libraries.

Related errors


AI-assisted analysis of siyuan-note/siyuan@9f775e8a12 (2026-09-19). Data as JSON: /api/errors/c9e692fff7c7a441. Report an issue: GitHub.

Appendix: source

Thrown at kernel/filesys/tree.go:255

	treenode.UpgradeSpec(tree)
	escapeAttributeValues(tree)
	return
}

func LoadTreeByData(data []byte, boxID, p string, luteEngine *lute.Lute) (ret *parse.Tree, err error) {
	ret, err = parseJSON2Tree(boxID, p, data, luteEngine)
	if nil != err {
		logging.LogErrorf("parse tree [%s] failed: %s", p, err)
		return
	}
	ret.Path = p
	ret.Root.Path = p

	hPath := "/" + strings.TrimPrefix(filepath.ToSlash(p), "/")
	parts := strings.Split(hPath, "/")
	if len(parts) < 2 {
		logging.LogErrorf("parse tree [%s] failed: invalid path", p)
		err = errors.New("invalid path")
		return
	}

	parts = parts[1 : len(parts)-1] // 去掉开头的斜杆和结尾的自己
	if 1 > len(parts) {
		ret.HPath = "/" + ret.Root.IALAttr("title")
		ret.Hash = treenode.NodeHash(ret.Root, ret, luteEngine)
		return
	}

	// 构造 HPath
	hPathBuilder := bytes.Buffer{}
	hPathBuilder.WriteString("/")
	for i := range parts {
		var parentAbsPath string
		if 0 < i {
			parentAbsPath = strings.Join(parts[:i+1], "/")
		} else {

View on GitHub (pinned to 9f775e8a12)