siyuan-note/siyuan · error

Query notebook failed

Error message

Query notebook failed

What it means

ResolveDocTreeSortMode is called by the listDocsByPath handler (POST /api/filetree/listDocsByPath, kernel/api/filetree.go:1317) whenever the request leaves sort unassigned; it resolves the effective sort mode from doc/notebook/global config. Conf.Box(boxID) returned nil — the notebook ID is unknown to the kernel — so the localized "Query notebook failed" (Conf.Language(0)) is returned and nothing is listed.

Solutions

  1. Fetch fresh IDs via POST /api/notebook/lsNotebooks and use a returned id
  2. Reopen the closed notebook (POST /api/notebook/openNotebook) before listing
  3. Re-issue the listing after notebook/workspace state changes settle
Defensive patterns

Strategy: validation

Validate before calling

if model.Conf.Box(boxID) == nil {
	return fmt.Errorf("notebook %s is not open or does not exist", boxID)
}
sortMode, err := model.ResolveDocTreeSortMode(boxID, listPath)

Type guard

func isNotebookListable(boxID string) bool {
	return model.Conf.Box(boxID) != nil
}

Prevention

When it happens

Trigger: POST /api/filetree/listDocsByPath (or listDocTree) with a notebook/box ID that is closed, deleted, or malformed; also when the notebook is closed between the UI load and the request.

Common situations: Stale box IDs cached by a plugin; notebook closed or removed mid-session; API called before the workspace finished loading; copy-pasted wrong ID.

Related errors


AI-assisted analysis of siyuan-note/siyuan@afa823b6b4 (2026-08-18). Data as JSON: /api/errors/fc5103da5c50f084. Report an issue: GitHub.

Appendix: source

Thrown at kernel/model/file.go:405

			ret.WriteRune('\\')
		}
		ret.WriteRune(r)
	}
	return ret.String()
}

type FileInfo struct {
	path  string
	name  string
	size  int64
	isdir bool
}

// ResolveDocTreeSortMode 按当前父文档、最近祖先文档、笔记本和全局配置的顺序解析子文档排序方式。
func ResolveDocTreeSortMode(boxID, listPath string) (sortMode int, err error) {
	box := Conf.Box(boxID)
	if nil == box {
		return 0, errors.New(Conf.Language(0))
	}

	normalized, err := box.validateBoxPath(listPath)
	if nil != err {
		return 0, err
	}
	normalized = filepath.ToSlash(normalized)
	if "" != normalized {
		docPath := "/" + strings.TrimPrefix(path.Clean("/"+normalized), "/")
		if !strings.HasSuffix(docPath, ".sy") {
			docPath += ".sy"
		}

		for "" != docPath && !IsBoxDocPath(boxID, docPath) {
			// 仅探测确实存在的文档,避免将同步中的临时缺失误判为损坏数据。
			if box.Exist(docPath) {
				if declared := docSortModeFromIAL(box.docIAL(docPath)); nil != declared {
					return *declared, nil

View on GitHub (pinned to afa823b6b4)