siyuan-note/siyuan · error

This is not a valid .sy.zip archive. If the archive was expo

Error message

This is not a valid .sy.zip archive. If the archive was exported from [Settings], please import it from [Settings]

What it means

After unzipping, importSY0 requires the archive root to contain exactly one entry and that entry to be a directory (the exported notebook/document folder). Any other top-level layout fails the '1 != len(entries) || !entries[0].IsDir()' guard and is rejected with the generic invalid-archive message Language(199). The actual entries are logged via LogErrorf for diagnosis.

Source

Thrown at kernel/model/import.go:206

			return err
		}
		if d == nil {
			return nil
		}
		if !d.IsDir() && strings.HasSuffix(d.Name(), ".sy") {
			syPaths = append(syPaths, path)
		}
		return nil
	})

	entries, err := os.ReadDir(unzipPath)
	if err != nil {
		logging.LogErrorf("read unzip dir [%s] failed: %s", unzipPath, err)
		return
	}
	if 1 != len(entries) || !entries[0].IsDir() {
		logging.LogErrorf("invalid .sy.zip [%v]", entries)
		err = errors.New(Conf.Language(199))
		return
	}
	unzipRootPath := filepath.Join(unzipPath, entries[0].Name())
	name := filepath.Base(unzipRootPath)
	if strings.HasPrefix(name, "data-20") && len("data-20230321175442") == len(name) {
		logging.LogErrorf("invalid .sy.zip [unzipRootPath=%s, baseName=%s]", unzipRootPath, name)
		err = errors.New(Conf.Language(199))
		return
	}
	var importedBoxConf *conf.BoxConf
	importedConfPath := filepath.Join(unzipRootPath, ".siyuan", "conf.json")
	hasImportedBoxConf := filelock.IsExist(importedConfPath)
	var importedMetadataErr error
	if hasImportedBoxConf {
		confData, readErr := filelock.ReadFile(importedConfPath)
		if readErr == nil {
			importedBoxConf = conf.NewBoxConf()
			if unmarshalErr := gulu.JSON.UnmarshalJSON(confData, importedBoxConf); unmarshalErr != nil {

View on GitHub (pinned to afa823b6b4)

Solutions

  1. Re-export from the source via right-click notebook/document - Export - .sy.zip; SiYuan always produces the correct single root folder
  2. If repacking manually, ensure the zip has exactly one top-level directory containing the .sy files and .siyuan metadata
  3. If the archive is really a Data export, import it from Settings - Import - Data instead; if it is Markdown, use /api/import/importStdMd

Example fix

# before: zip of the folder contents (multiple/dangling root entries)
zip -r out.zip .            # INVALID for .sy.zip import

# after: zip that preserves the single root directory
zip -r out.zip 20230321175442-xxxxxxx/   # one top-level dir holding the .sy tree
Defensive patterns

Strategy: validation

Validate before calling

func hasSingleRootDir(zipPath string) bool {
    r, err := zip.OpenReader(zipPath)
    if err != nil {
        return false
    }
    defer r.Close()
    roots := map[string]struct{}{}
    for _, f := range r.File {
        name := strings.TrimPrefix(f.Name, "./")
        if name == "" {
            continue
        }
        parts := strings.SplitN(name, "/", 2)
        roots[parts[0]] = struct{}{}
    }
    return len(roots) == 1
}

Type guard

func isInvalidSYZipErr(err error) bool {
    return err != nil && err.Error() == model.Conf.Language(199)
}

Try / catch

if err := model.ImportSY(zipPath, boxID, toPath); err != nil {
    if err.Error() == model.Conf.Language(199) {
        // tell the user the archive layout is invalid; do not retry the same file
    }
}

Prevention

When it happens

Trigger: Any importSY-family call with a zip whose top level has zero entries, more than one entry, or a file at the root: hand-built zips that selected the folder's contents instead of the folder, archives re-packed by mail/cloud tools that flattened the root, double-zipped archives, or an empty zip.

Common situations: User right-clicks the exported folder and zips selected files, losing the single-root layout. A transfer service re-packs attachments. The user actually has a full Data export (see also error 802) or a Markdown archive, not a .sy.zip.

Related errors


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