{"record":{"id":"d83816e4d00bba6c","repo":"siyuan-note/siyuan","slug":"this-is-not-a-valid-data-archive-if-the-archive-w","errorCode":null,"errorMessage":"This is not a valid Data archive. If the archive was exported from [Documents], please import it from [Documents]","messagePattern":"This is not a valid Data archive\\. If the archive was exported from \\[Documents\\], please import it from \\[Documents\\]","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"kernel/model/import.go","lineNumber":1131,"sourceCode":"\n\tlogging.LogInfof(\"import data from [%s]\", zipPath)\n\tbaseName := filepath.Base(zipPath)\n\text := filepath.Ext(baseName)\n\tbaseName = strings.TrimSuffix(baseName, ext)\n\tunzipPath := filepath.Join(filepath.Dir(zipPath), baseName)\n\terr = gulu.Zip.Unzip(zipPath, unzipPath)\n\tif err != nil {\n\t\treturn\n\t}\n\tdefer os.RemoveAll(unzipPath)\n\n\tfiles, err := filepath.Glob(filepath.Join(unzipPath, \"*/*.sy\"))\n\tif err != nil {\n\t\tlogging.LogErrorf(\"check data.zip failed: %s\", err)\n\t\treturn errors.New(\"check data.zip failed\")\n\t}\n\tif 0 < len(files) {\n\t\treturn errors.New(Conf.Language(198))\n\t}\n\tdirs, err := os.ReadDir(unzipPath)\n\tif err != nil {\n\t\tlogging.LogErrorf(\"check data.zip failed: %s\", err)\n\t\treturn errors.New(\"check data.zip failed\")\n\t}\n\tif 1 != len(dirs) {\n\t\treturn errors.New(Conf.Language(198))\n\t}\n\n\ttmpDataPath := filepath.Join(unzipPath, dirs[0].Name())\n\ttmpDataEmojisPath := filepath.Join(tmpDataPath, \"emojis\")\n\tfilelock.Walk(tmpDataEmojisPath, func(path string, d fs.DirEntry, err error) error {\n\t\tif err != nil {\n\t\t\treturn err\n\t\t}\n\t\tif d == nil {\n\t\t\treturn nil","sourceCodeStart":1113,"sourceCodeEnd":1149,"githubUrl":"https://github.com/siyuan-note/siyuan/blob/251596fc0de2f9528c00c224252fd073a99973f4/kernel/model/import.go#L1113-L1149","documentation":"Thrown by ImportData (language code 198) when the glob finds .sy files directly at the first nesting level inside the unzipped archive (matching */*.sy). This structure indicates the archive was exported from a single notebook or document (the Documents export path), not a full Data export. Data archives wrap everything under a single top-level data-root directory and do not have .sy files at this level. The error message guides the user to use the correct import path.","triggerScenarios":"Calling ImportData with a zip that was exported via the Documents/notebook export function rather than the Data export function. The glob at import.go:1125 finds one or more .sy files matching the */*.sy pattern, triggering the check at import.go:1130-1132.","commonSituations":"User exports a notebook as .sy.zip, then tries to import it through the Data import menu instead of the notebook/document import. User confuses the two export formats. User receives a .zip from someone who exported from Documents, not Data.","solutions":["Use the correct import path: import notebook/document .sy.zip archives through the notebook import menu, not the Data import menu.","If you need to import as Data, re-export using Settings - Export - Export Data.","Check the archive structure: Data exports have a single top-level directory containing notebooks; document exports have .sy files at a shallower level."],"exampleFix":null,"handlingStrategy":"validation","validationCode":"// Check archive type before choosing import function\nfunc isDataArchive(zipPath string) (bool, error) {\n    tmpDir, err := os.MkdirTemp(\"\", \"sy-check-\")\n    if err != nil {\n        return false, err\n    }\n    defer os.RemoveAll(tmpDir)\n    if err := gulu.Zip.Unzip(zipPath, tmpDir); err != nil {\n        return false, err\n    }\n    // Data archives have no .sy files at */*.sy level\n    matches, _ := filepath.Glob(filepath.Join(tmpDir, \"*/*.sy\"))\n    if len(matches) > 0 {\n        return false, nil // looks like a document/notebook export\n    }\n    dirs, err := os.ReadDir(tmpDir)\n    if err != nil || len(dirs) != 1 {\n        return false, nil\n    }\n    return true, nil\n}\n\n// Usage:\nisData, _ := isDataArchive(zipPath)\nif !isData {\n    return errors.New(\"use notebook/document import for this archive type\")\n}","typeGuard":null,"tryCatchPattern":"err := model.ImportData(zipPath)\nif err != nil {\n    if err.Error() == Conf.Language(198) {\n        // Wrong archive type — guide user to correct import menu\n        util.PushMsg(\"This is a document archive. Use the notebook import menu instead.\")\n    }\n}","preventionTips":["Educate users on the difference between Data export and notebook/document export.","In the UI, distinguish the import menu items clearly (Import Data vs Import Notebook/Document).","Before calling ImportData, validate the archive structure to give a more specific error.","Check the archive contents: Data exports have a single data-root directory; document exports have .sy files at a shallower level."],"tags":["import","data-zip","validation","user-error","format-mismatch"],"backgroundTag":null,"analyzedSha":"251596fc0de2f9528c00c224252fd073a99973f4","analyzedAt":"2026-08-12T21:18:37.123Z","schemaVersion":2},"datasetVersion":"2026-08-12T23:17:12.415Z"}