siyuan-note/siyuan · error

target document [%s] is unavailable

Error message

target document [%s] is unavailable

What it means

ReorderDocTree validates that the reorder target document exists in the block tree, is a sortable document, and belongs to a notebook currently known to the kernel (Conf.Box). If any of these fail, it returns this error instead of reordering. It protects against reordering around a target that is deleted, moved, corrupted in the index, or in a notebook that is closed.

Source

Thrown at kernel/model/file_tree_reorder.go:111

	inherited, err := ResolveDocTreeSortMode(boxID, parentPath)
	if err != nil {
		return nil, err
	}
	if inherited == util.SortModeCustom {
		return nil, nil
	}
	return &mode, nil
}

// ReorderDocTree 在移动前检查完整列表,确认冲突后仅设置目标列表的排序方式。
func ReorderDocTree(sourceIDs []string, targetID, position string, preview, removeSorts bool) (ret *DocTreeReorderResult, err error) {
	if err = validateReorderArgs(sourceIDs, targetID, position); err != nil {
		return
	}
	FlushTxQueue()
	target := treenode.GetBlockTree(targetID)
	if !isSortableDocument(target) || Conf.Box(target.BoxID) == nil {
		return nil, fmt.Errorf("target document [%s] is unavailable", targetID)
	}
	box := Conf.Box(target.BoxID)
	parentDir := path.Dir(target.Path)
	confPath := filepath.Join(util.DataDir, box.ID, ".siyuan", "sort.json")
	existingSorts, err := readSortConfMap(confPath)
	if err != nil {
		return nil, err
	}
	listPath := parentDir
	if listPath != "/" {
		listPath += ".sy"
	}
	mode, err := ResolveDocTreeSortMode(box.ID, listPath)
	if err != nil {
		return nil, err
	}
	// 隐藏文档和超过显示上限的文档也必须参与排序。
	docs, _, err := ListDocTree(box.ID, listPath, mode, false, true, int(^uint(0)>>1))

View on GitHub (pinned to 8641553a1f)

Solutions

  1. Confirm the target document exists and refresh: POST /api/filetree/getDoc with targetID
  2. Re-open the target notebook (POST /api/notebook/openNotebook) if it was closed
  3. Call POST /api/filetree/refreshFiletree or restart sync to rebuild the block-tree index, then retry
  4. Verify targetID is a full 22-character block ID of an existing .sy document
  5. Re-check the doc tree listing to obtain a valid current target ID before reordering

Example fix

// before (target deleted by sync between drag and drop)
await fetchPost('/api/filetree/reorderDocs', {sourceIDs, targetID: draggedOverID, position});
// after (guard on live tree data)
const tree = await fetchPost('/api/filetree/listDocsByPath', {notebook, path: parentPath});
if (!tree.data.files.some(f => f.id === draggedOverID)) {
  return showError('Target document no longer exists');
}
await fetchPost('/api/filetree/reorderDocs', {sourceIDs, targetID: draggedOverID, position});
Defensive patterns

Strategy: validation

Validate before calling

async function canReorder(targetId) {
  const r = await fetchPost('/api/filetree/getDocInfo', {id: targetId});
  return r && r.data && r.data.id === targetId;
}
if (!(await canReorder(targetId))) await refreshFiletree();

Type guard

function isFullBlockId(v) { return typeof v === 'string' && /^[0-9]{14}-[a-z0-9]{7}$/.test(v); }

Try / catch

try {
  await fetchPost('/api/filetree/reorderDocs', {sourceIDs, targetID, position});
} catch (e) {
  if (String(e).includes('target document') && String(e).includes('unavailable')) {
    await fetchPost('/api/filetree/refreshFiletree', {});
    showMsg('Target document is gone; tree refreshed', true);
  }
}

Prevention

When it happens

Trigger: Calling ReorderDocTree (or reorderDocs API path) with targetID that has no block-tree record (deleted/unindexed doc), is not a sortable document (e.g. a special/system path), or whose notebook is closed or removed (Conf.Box returns nil).

Common situations: Drag-drop onto a document deleted by another client or sync between drag start and drop; notebook closed while the tree view still shows its docs; stale tree cache after bulk reorganization; targetID typo in API scripts.

Understand the failure class

Background: "Not found" and "does not exist" errors: why "Task not found", "No such folder", and "Can't find" fire when a lookup comes back empty — this error's family across 14 libraries.

Related errors


AI-assisted analysis of siyuan-note/siyuan@8641553a1f (2026-09-11). Data as JSON: /api/errors/0c597390c3cf44bd. Report an issue: GitHub.