siyuan-note/siyuan · error

read imported notebook conf

Error message

read imported notebook conf [%s] failed: %w

What it means

validateImportedNotebookIdentities, run by ImportData before notebooks are merged into the workspace, reads each imported notebook's .siyuan/conf.json via filelock.ReadFile. If that read fails (I/O error, lock, permission), it returns a wrapped 'read imported notebook conf [%s] failed' error naming the boxID, aborting the whole import since notebook identity (especially encryption identity) cannot be verified.

Solutions

  1. Check the kernel log / wrapped readErr for the underlying OS error and path, then fix that cause (permissions, lock, disk).
  2. Re-extract or re-export the import archive so .siyuan/conf.json is intact and readable.
  3. Exclude the workspace from antivirus/sync clients that hold files open, then retry ImportData.
  4. Manually verify the file: open .siyuan/conf.json inside the imported notebook folder as the same user running the kernel; fix permissions if unreadable.
Defensive patterns

Strategy: validation

Validate before calling

const confPath = path.join(boxDir, '.siyuan', 'conf.json');
await fs.promises.access(confPath, fs.constants.R_OK); // throws early if unreadable

Try / catch

try {
  await importData(src);
} catch (e) {
  if (/read imported notebook conf/.test(e.msg)) {
    console.error('Fix permissions/locks on the imported notebook\'s .siyuan/conf.json, then retry');
  }
  throw e;
}

Prevention

When it happens

Trigger: ImportData encountering an imported notebook directory that contains .siyuan/conf.json but where reading that file fails — permission denied, file locked by another process, or disk/IO error during import extraction.

Common situations: 1) Antivirus or a sync client (OneDrive/Dropbox) locking conf.json during import on Windows. 2) Partially extracted archive leaving conf.json unreadable or a broken symlink. 3) Workspace restored from backup with wrong ownership. 4) Failing disk sector.

Understand the failure class

Background: "failed to read file", EACCES, ENOENT and "could not read <path>" errors: when a program can't read a file from disk — this error's family across 49 libraries.

Related errors


AI-assisted analysis of siyuan-note/siyuan@9f775e8a12 (2026-09-19). Data as JSON: /api/errors/b68074cb53921f44. Report an issue: GitHub.

Appendix: source

Thrown at kernel/model/import.go:1336

		return nil, err
	}

	var encryptedBoxIDs []string
	for _, entry := range dirs {
		if !entry.IsDir() || !ast.IsNodeIDPattern(entry.Name()) {
			continue
		}

		boxID := entry.Name()
		boxDir := filepath.Join(tmpDataPath, boxID)
		confPath := filepath.Join(boxDir, ".siyuan", "conf.json")
		backupPath := filepath.Join(boxDir, ".siyuan", notebookCryptoBackupFilename)

		var boxConf *conf.BoxConf
		if filelock.IsExist(confPath) {
			data, readErr := filelock.ReadFile(confPath)
			if readErr != nil {
				return nil, fmt.Errorf("read imported notebook conf [%s] failed: %w", boxID, readErr)
			}
			boxConf = conf.NewBoxConf()
			if unmarshalErr := gulu.JSON.UnmarshalJSON(data, boxConf); unmarshalErr != nil {
				return nil, fmt.Errorf("parse imported notebook conf [%s] failed: %w", boxID, unmarshalErr)
			}
		}

		var backup *conf.BoxEncryption
		if filelock.IsExist(backupPath) {
			backup, err = readBoxEncryptionFile(backupPath)
			if err != nil {
				return nil, fmt.Errorf("invalid imported notebook identity [%s]: %w", boxID, err)
			}
		}

		var boxCrypt *conf.BoxEncryption
		if boxConf != nil && boxConf.Encrypted {
			if boxConf.BoxCrypt != nil && validateBoxEncryption(boxConf.BoxCrypt) == nil {

View on GitHub (pinned to 9f775e8a12)