siyuan-note/siyuan · error

Conf.Language(199)

Error message

Conf.Language(199)

What it means

importSY0 validates the shape of an unpacked .sy.zip: the unzip directory must contain exactly one entry and it must be a directory. Anything else is rejected with i18n key 199 ('This is not a valid .sy.zip archive...'). This guards against arbitrary zips or archives with files at the root.

Source

Thrown at kernel/model/import.go:353

			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 8641553a1f)

Solutions

  1. Re-export the .sy.zip from SiYuan (doc tree or Settings) without modifying the archive structure
  2. Ensure the zip contains exactly one root directory (e.g. the notebook export folder)
  3. If re-packaging manually, wrap all contents in a single top-level directory before zipping
  4. Verify the archive is not corrupted (test extraction) before importing
Defensive patterns

Strategy: validation

Validate before calling

// validate zip layout before import: exactly one top-level directory
f, _ := zip.OpenReader(zipPath)
defer f.Close()
tops := map[string]bool{}
for _, zf := range f.File {
    parts := strings.SplitN(zf.Name, "/", 2)
    tops[parts[0]] = true
}
if len(tops) != 1 {
    return errors.New("zip must contain a single root directory")
}

Try / catch

// Go caller
if err := model.ImportSY(zipPath, boxID, toPath); err != nil {
    logging.LogErrorf("invalid .sy.zip layout: %s", err)
    return fmt.Errorf("please re-export the archive from SiYuan")
}

Prevention

When it happens

Trigger: Calling ImportSY / ImportSYAuto / ImportSYNotebookBundle with a zip that, after unzip, yields multiple entries at the top level or a top-level file instead of a single directory (e.g. a .sy.zip without its enclosing folder, a renamed random .zip, or a corrupted archive).

Common situations: Manually re-zipping documents without the single root folder; downloading a partial archive; passing a plain zip of .sy files instead of the exported .sy.zip; macOS archive tools that strip the wrapper folder.

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


AI-assisted analysis of siyuan-note/siyuan@8641553a1f (2026-09-11). Data as JSON: /api/errors/612945c186c7f1b9. Report an issue: GitHub.