siyuan-note/siyuan · error

Conf.Language(20)

Error message

Conf.Language(20)

What it means

Doc2Heading removes the source document's folder after converting it to heading content. If that folder still contains sub-documents (not empty), the conversion would lose child documents, so the kernel aborts with Conf.Language(20) — 'Cannot be converted to heading when including sub-documents'.

Source

Thrown at kernel/model/heading.go:195

		return
	}

	FlushTxQueue()

	srcTree, _ := LoadTreeByBlockID(srcID)
	if nil == srcTree {
		err = ErrBlockNotFound
		return
	}
	if IsBoxDoc(srcTree.Box, srcTree.ID) {
		err = errors.New(Conf.Language(341))
		return
	}

	subDir := filepath.Join(util.DataDir, srcTree.Box, strings.TrimSuffix(srcTree.Path, ".sy"))
	if gulu.File.IsDir(subDir) {
		if !util.IsEmptyDir(subDir) {
			err = errors.New(Conf.Language(20))
			return
		}

		if removeErr := os.Remove(subDir); nil != removeErr { // 移除空文件夹不会有副作用
			logging.LogWarnf("remove empty dir [%s] failed: %s", subDir, removeErr)
		}
	}

	if nil == treenode.GetBlockTree(targetID) {
		// 目标块不存在时忽略处理
		return
	}

	targetTree, _ := LoadTreeByBlockID(targetID)
	if nil == targetTree {
		// 目标块不存在时忽略处理
		return
	}

View on GitHub (pinned to 8641553a1f)

Solutions

  1. Move or convert the child documents first, then convert the (now leaf) source document
  2. Use 'move document' instead of doc2Heading when the source has sub-documents
  3. Recursively flatten children into their own headings in multiple calls
Defensive patterns

Strategy: validation

Validate before calling

// ensure the source doc has no sub-documents before doc2Heading
const children = await getChildDocs(boxID, srcPath);
if (children.length > 0) throw new Error('move or flatten sub-documents first');

Try / catch

try {
  await fetchPost('/api/filetree/doc2Heading', {srcID, targetID});
} catch (e) {
  if (String(e.msg).includes('sub-documents')) {
    // offer user to move children first
  } else throw e;
}

Prevention

When it happens

Trigger: Calling Doc2Heading on a document that has nested child documents beneath data/<box>/<docpath>/ on disk.

Common situations: Users restructuring notebooks who try to flatten a parent doc that still has children; scripts assuming the doc is a leaf.

Understand the failure class

Background: "Invalid state transition" errors: "status must be X, actually Y", "already rejected/charging/uninstalled", "cannot ... while running" — what they mean when a library rejects your call — this error's family across 31 libraries.

Related errors


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