siyuan-note/siyuan · error

199

199

Error message

Conf.Language(199)

What it means

Thrown by ImportSYNotebookBundle while scanning a .sy.zip bundle: a manifest entry matched the bundle manifest path suffix, but its location is invalid — the manifest sits at the archive root (empty candidate), is nested deeper than one folder level (contains "/"), or more than one manifest was found (rootName already set). Localized as Conf.Language(199): invalid .sy.zip archive. The function returns bundle=true, telling the caller the archive claims to be a bundle but is malformed.

Solutions

  1. Re-export the notebook bundle from 设置 - 导出 - 导出 Notebook bundle so the layout is canonical
  2. If repacking manually, keep exactly one manifest at <single-root>/manifest path and no second copy anywhere
  3. Import plain single-notebook .sy.zip exports through the normal import flow instead of the bundle path
Defensive patterns

Strategy: try-catch

Try / catch

ids, bundle, err := model.ImportSYNotebookBundle(zipPath)
if err != nil {
    if err.Error() == Conf.Language(199) && bundle {
        // bundle claims to be one but its manifest layout is invalid: re-export from SiYuan
    }
    return err
}

Prevention

When it happens

Trigger: Importing a .sy.zip that contains a manifest.json in two different folders or at the top level. Typically produced by hand-repacking a bundle export or by tools that inject extra manifest files.

Common situations: Users re-zipping a bundle export with the wrong root level; archive tools adding duplicate metadata entries; merging two bundle exports into one zip.

Related errors


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

Appendix: source

Thrown at kernel/model/notebook_bundle.go:218

// ImportSYNotebookBundle 导入批量笔记本包。普通 .sy.zip 返回 bundle=false,由原有导入流程继续处理。
func ImportSYNotebookBundle(zipPath string) (boxIDs []string, bundle bool, err error) {
	archive, openErr := zip.OpenReader(zipPath)
	if nil != openErr {
		err = openErr
		return
	}
	var manifestData []byte
	rootName := ""
	manifestSuffix := "/" + syNotebookBundleManifestPath
	for _, file := range archive.File {
		if !strings.HasSuffix(file.Name, manifestSuffix) {
			continue
		}
		candidateRoot := strings.TrimSuffix(file.Name, manifestSuffix)
		if candidateRoot == "" || strings.Contains(candidateRoot, "/") || rootName != "" {
			_ = archive.Close()
			return nil, true, errors.New(Conf.Language(199))
		}
		reader, readErr := file.Open()
		if nil != readErr {
			_ = archive.Close()
			return nil, true, readErr
		}
		manifestData, readErr = io.ReadAll(reader)
		_ = reader.Close()
		if nil != readErr {
			_ = archive.Close()
			return nil, true, readErr
		}
		rootName = candidateRoot
	}
	_ = archive.Close()
	if rootName == "" {
		return nil, false, nil
	}

View on GitHub (pinned to afa823b6b4)