{"record":{"id":"4379a20324952f36","repo":"siyuan-note/siyuan","slug":"this-archive-contains-notebook-data-please-import","errorCode":null,"errorMessage":"This archive contains notebook data. Please import it from [Document Tree - More - Import Notebook]","messagePattern":"This archive contains notebook data\\. Please import it from \\[Document Tree - More - Import Notebook\\]","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"kernel/model/import.go","lineNumber":141,"sourceCode":"\t\t\t\tn.Tokens = bytes.ReplaceAll(n.Tokens, []byte(\"|\"), []byte(\"\\\\|\"))\n\t\t\t\tn.Tokens = bytes.ReplaceAll(n.Tokens, []byte(\"\\\\<br /\\\\>\"), []byte(\"<br />\"))\n\t\t\t}\n\t\tcase ast.NodeInlineMath:\n\t\t\twithMath = true\n\t\tcase ast.NodeLinkDest:\n\t\t\tdest := n.TokensStr()\n\t\t\tif strings.HasPrefix(dest, \"data:image\") && strings.Contains(dest, \";base64,\") {\n\t\t\t\tprocessBase64Img(n, dest, assetDirPath, boxID)\n\t\t\t}\n\t\t}\n\t\treturn ast.WalkContinue\n\t})\n\treturn\n}\n\nfunc ImportSY(zipPath, boxID, toPath string) (err error) {\n\tif isSYNotebookBundle(zipPath) {\n\t\treturn errors.New(Conf.Language(373))\n\t}\n\t_, err = importSY(zipPath, boxID, toPath, false, false)\n\treturn\n}\n\nfunc ImportSYNotebook(zipPath string) (boxID string, err error) {\n\treturn importSY(zipPath, \"\", \"/\", true, false)\n}\n\nvar ErrSYTargetNotebookRequired = errors.New(\"target notebook required\")\n\nfunc ImportSYAuto(zipPath, boxID, toPath string) (createdBoxID string, notebook bool, err error) {\n\tcreatedBoxID, err = importSY(zipPath, boxID, toPath, false, true)\n\tnotebook = err == nil && createdBoxID != boxID\n\treturn\n}\n\nfunc isSYNotebookExport(hasBoxConf, hasBoxDocMeta bool) bool {","sourceCodeStart":123,"sourceCodeEnd":159,"githubUrl":"https://github.com/siyuan-note/siyuan/blob/afa823b6b4e4f183511e0bc0a3be93caa94c7c97/kernel/model/import.go#L123-L159","documentation":"Thrown by model.ImportSY (kernel/model/import.go:141) when the supplied .sy.zip is actually a multi-notebook bundle export. isSYNotebookBundle detects the batch format by looking for a '.siyuan/notebooks.json' manifest entry anywhere in the zip (see kernel/model/notebook_bundle.go:64). Bundle archives are only understood by the notebook-import path, so the document-import endpoint refuses them up front with the localized Language(373) message pointing at Document Tree - More - Import Notebook.","triggerScenarios":"POST /api/import/importSY (or /api/import/continueImportSY, or a direct model.ImportSY call) with an archive produced by batch notebook export, i.e. any zip containing an entry ending in '/.siyuan/notebooks.json'. The check runs before unzipping, so the error is immediate.","commonSituations":"User selects several notebooks and exports them as one archive from the document tree, then feeds that file to the doc-level '.sy.zip' import (wrong menu item). Automation scripts or plugins that always call importSY regardless of archive kind. Dragging a bundle onto the doc tree in an older build that lacked auto-detection.","solutions":["Import the file via the notebook path instead: POST /api/import/importSYNotebook, which first tries model.ImportSYNotebookBundle and handles bundles (UI: Document Tree - More - Import Notebook)","Or call POST /api/import/importSYAuto, which auto-dispatches bundle, notebook, and document archives","If you truly need a document-level import, re-export just the document (not the whole notebook) as .sy.zip from the source instance"],"exampleFix":"// before\nerr := model.ImportSY(zipPath, boxID, toPath) // fails: bundle rejected with Language(373)\n\n// after\nif ids, bundle, bundleErr := model.ImportSYNotebookBundle(zipPath); bundle {\n    // ids = created notebook IDs; bundleErr handled separately\n} else if bundleErr == nil {\n    boxID, err := model.ImportSYNotebook(zipPath)\n}","handlingStrategy":"validation","validationCode":"func isNotebookBundle(zipPath string) bool {\n    r, err := zip.OpenReader(zipPath)\n    if err != nil {\n        return false\n    }\n    defer r.Close()\n    for _, f := range r.File {\n        if strings.HasSuffix(f.Name, \"/.siyuan/notebooks.json\") {\n            return true\n        }\n    }\n    return false\n}\n\nif isNotebookBundle(zipPath) {\n    // route to /api/import/importSYNotebook instead of importSY\n}","typeGuard":null,"tryCatchPattern":"if err := model.ImportSY(zipPath, boxID, toPath); err != nil {\n    if err.Error() == model.Conf.Language(373) {\n        // archive is notebook data: re-dispatch via model.ImportSYNotebook / ImportSYNotebookBundle\n        return\n    }\n    // other failures: surface to user\n}","preventionTips":["Prefer /api/import/importSYAuto - it dispatches bundles and notebook/doc exports itself","When building import UI, offer one entry point that auto-classifies the archive instead of separate fixed endpoints","Compare error text against model.Conf.Language(373) rather than hardcoding English strings - messages are localized"],"tags":["siyuan","import","sy-zip","notebook-bundle","validation"],"backgroundTag":"import-archive-type-mismatch","analyzedSha":"afa823b6b4e4f183511e0bc0a3be93caa94c7c97","analyzedAt":"2026-08-18T17:04:10.865Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-14T00:17:10.932Z"}