siyuan-note/siyuan · error
renderDocRef path target must be a document path
Error message
renderDocRef path target must be a document path
What it means
In renderDocRef "path" mode, the target must be a string containing the human-readable path of a document in the current doc tree. If the value is not a string, the call fails with "renderDocRef path target must be a document path". Note the check happens before path cleaning and matching, so any non-string type triggers it immediately.
Source
Thrown at kernel/model/template_doc_tree.go:263
switch mode {
case "children":
id, ok := value.(string)
if !ok {
return nil, errors.New("renderDocRef children target must be a document ID")
}
if collector.rootID == id {
return collector.nodes, nil
}
for _, node := range flattenTemplateDocTreeNodes0(collector.nodes) {
if node.ID == id {
return node.Children, nil
}
}
return []*TemplateDocTreeNode{}, nil
case "path":
hPath, ok := value.(string)
if !ok {
return "", errors.New("renderDocRef path target must be a document path")
}
requestedPath := path.Clean(hPath)
for _, node := range flattenTemplateDocTreeNodes0(collector.nodes) {
relativePath := strings.TrimPrefix(node.HPath, collector.rootHPath)
if node.HPath == requestedPath || relativePath == requestedPath {
return fmt.Sprintf("((%s %q))", node.RootID, node.HPath), nil
}
}
return "", nil
default:
return nil, fmt.Errorf("unsupported renderDocRef query mode [%s]", mode)
}
}
func flattenTemplateDocTreeNodes0(nodes []*TemplateDocTreeNode) (ret []*TemplateDocTreeNode) {
for _, node := range nodes {
ret = append(ret, node)
ret = append(ret, flattenTemplateDocTreeNodes0(node.Children)...)View on GitHub (pinned to 8641553a1f)
Solutions
- Pass a quoted path string: renderDocRef("path", "/Parent/Child").
- Ensure interpolated variables produce strings (apply string formatting).
- Use the node's hPath value, not the node object itself.
Example fix
// before
renderDocRef("path", ."/Docs/" . $n) // $n is a number, still a string — but raw node objects are not
// after
renderDocRef("path", "/Docs/Chapter 1") Defensive patterns
Strategy: type-guard
Validate before calling
if (typeof target !== "string") throw new Error("path target must be a string hPath"); Type guard
const isHPath = (v) => typeof v === "string" && v.startsWith("/"); Try / catch
try {
const ref = renderDocRef("path", target);
} catch (e) {
if (String(e).includes("must be a document path")) {
// convert node objects/ids to their hPath string
}
} Prevention
- Pass the node's hPath string, never the node object
- Validate interpolation results are strings before passing
- Document that path mode expects a slash-prefixed path string
When it happens
Trigger: Calling renderDocRef("path", 42), renderDocRef("path", nil), or passing a list/object where a path string like "/Parent/Child" is expected.
Common situations: Template variable interpolation that yields a non-string; passing node data structures instead of their hPath string; typos where the ID was given to the path mode (that returns empty, but a wrong type errors).
Understand the failure class
Background: Type mismatch errors: IllegalArgumentException, TypeError and type guards across 150 open-source libraries — this error's family across 150 libraries.
Related errors
- renderDocRef children target must be a document ID
- new item template field [%s] current time value is invalid
- new item template field [%s] value is invalid
- createDocTree definition must be a list
- createDocTree document must be a dictionary
AI-assisted analysis of siyuan-note/siyuan@8641553a1f (2026-09-11).
Data as JSON: /api/errors/022356b6b4e5ad52.
Report an issue: GitHub.