siyuan-note/siyuan · error
Conf.Language(199)
Error message
Conf.Language(199)
What it means
ImportSYNotebookBundle imports a multi-notebook bundle (.sy.zip containing a bundle manifest). While scanning the archive for a `*/manifest.json` bundle entry, it found a manifest path that is structurally invalid: the candidate root folder is empty, nested (contains '/'), or a second manifest was found after one was already accepted. The library rejects such archives because a bundle must contain exactly one top-level folder holding exactly one manifest.
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 8641553a1f)
Solutions
- Rebuild the bundle so the zip contains exactly one top-level folder with manifest.json directly inside it and no other manifest.json anywhere in the archive
- Open the .sy.zip and inspect entry names (unzip -l) to find duplicate or nested manifest.json files and remove the extras
- Re-export the bundle from SiYuan's export-bundle feature instead of manually repackaging
- If the file is a plain single-notebook .sy.zip (no manifest), do not call ImportSYNotebookBundle; use the normal single-notebook import path, which is tried when bundle=false
Example fix
// before: zip layout 'outer/inner/manifest.json' or two manifests // after: exactly one root folder // bundle/ // manifest.json // notebooks/Notebook1.sy.zip
Defensive patterns
Strategy: validation
Validate before calling
// Inspect zip entries before import (Node.js example)
const entries = (await getZipEntryNames(bundlePath));
const manifests = entries.filter(n => n.endsWith('/manifest.json'));
if (manifests.length !== 1) throw new Error('bundle must contain exactly one manifest');
const root = manifests[0].slice(0, -('/manifest.json'.length));
if (!root || root.includes('/')) throw new Error('manifest must sit in a single top-level folder'); Try / catch
try {
const { boxIDs, bundle } = await importSYNotebookBundle(zipPath);
if (!bundle) return importSingleNotebook(zipPath); // bundle=false means plain .sy.zip
} catch (e) {
if (e.message.includes('invalid') || isLocalizedBundleError(e)) showUserHint('Rebuild the bundle: exactly one top-level folder with one manifest.json');
else throw e;
} Prevention
- Always create bundles with SiYuan's built-in export instead of manual re-zipping
- Run unzip -l and grep for manifest.json occurrences; expect exactly one
- Never nest bundle folders inside bundle folders when redistributing
When it happens
Trigger: Calling ImportSYNotebookBundle (via the import .sy.zip API endpoint) on a zip where: (a) the manifest sits at the archive root (candidateRoot == "", e.g. 'manifest.json' with no folder prefix is matched by suffix '/manifest.json'? actually an entry named exactly with empty prefix), (b) a manifest exists in a nested subfolder like 'outer/inner/manifest.json', or (c) the zip contains two or more manifest files in different top-level folders.
Common situations: Hand-assembled or re-zipped bundles where the zip tool wrapped folders twice (e.g. 'Bundle/Bundle/manifest.json'), bundles produced by old/custom export scripts that place the manifest at the archive root, or concatenated archives that accidentally include manifests from multiple exports.
Understand the failure class
Background: "Invalid ... format", "must be in format X", "does not look like a ..." — invalid argument format errors across CLI tools and libraries — this error's family across 17 libraries.
Related errors
- This archive contains notebook data. Please import it from [
- This is not a valid .sy.zip archive. If the archive was expo
- Query notebook failed
- Encrypted notebooks do not support this operation
- 199
AI-assisted analysis of siyuan-note/siyuan@8641553a1f (2026-09-11).
Data as JSON: /api/errors/7da5e1b326472deb.
Report an issue: GitHub.