siyuan-note/siyuan · error

read master password migration failed: %w

Error message

read master password migration failed: %w

What it means

readMasterPasswordMigrationUnlocked could not read the existing master password migration file from disk via filelock.ReadFile. The migration state cannot be loaded, so callers (readMasterPasswordMigration, removeMasterPasswordMigrationBox) receive this wrapped error instead of the record.

Source

Thrown at kernel/model/crypto.go:562

		return fmt.Errorf("marshal master password migration failed: %w", err)
	}
	return filelock.WriteFile(p, data)
}

func readMasterPasswordMigration() (*masterPasswordMigration, error) {
	masterPasswordMigrationMu.Lock()
	defer masterPasswordMigrationMu.Unlock()
	return readMasterPasswordMigrationUnlocked()
}

func readMasterPasswordMigrationUnlocked() (*masterPasswordMigration, error) {
	p := masterPasswordMigrationPath()
	if !filelock.IsExist(p) {
		return nil, nil
	}
	data, err := filelock.ReadFile(p)
	if err != nil {
		return nil, fmt.Errorf("read master password migration failed: %w", err)
	}
	var m masterPasswordMigration
	if err = gulu.JSON.UnmarshalJSON(data, &m); err != nil {
		return nil, fmt.Errorf("unmarshal master password migration failed: %w", err)
	}
	return &m, nil
}

func removeMasterPasswordMigration() {
	masterPasswordMigrationMu.Lock()
	defer masterPasswordMigrationMu.Unlock()
	removeMasterPasswordMigrationUnlocked()
}

func removeMasterPasswordMigrationUnlocked() {
	p := masterPasswordMigrationPath()
	if err := filelock.Remove(p); err != nil && !os.IsNotExist(err) {
		logging.LogErrorf("remove master password migration failed: %s", err)

View on GitHub (pinned to 8641553a1f)

Solutions

  1. Fix file permissions on the migration file so the kernel process can read it
  2. Close processes locking the file (sync clients, antivirus, second SiYuan instance)
  3. Check disk health / OS event logs for I/O errors
  4. If the file is unrecoverable, restore it from backup or re-run the migration; note the existing record cannot be authenticated-read
  5. Verify the file is not a directory or symlink pointing outside the workspace

Example fix

// before: unreadable migration file
-rw------- root root migration.json
// after
sudo chown $USER migration.json
m, err := readMasterPasswordMigration()
Defensive patterns

Strategy: try-catch

Validate before calling

p := masterPasswordMigrationPath()
if fi, err := os.Stat(p); err == nil && fi.Mode().Perm()&0400 == 0 {
    return fmt.Errorf("migration file not readable by current user")
}

Try / catch

m, err := readMasterPasswordMigration()
if err != nil {
    if os.IsPermission(errors.Unwrap(err)) {
        // prompt: fix file ownership/permissions
    }
    return err // do not treat unreadable existing state as 'no migration'
}

Prevention

When it happens

Trigger: The migration file exists (filelock.IsExist returned true) but opening/reading it fails — permission denied, file locked by another process, or I/O error on the disk.

Common situations: File owned by another user after restoring a data directory, the file locked by antivirus or a sync client (OneDrive/Dropbox), or hardware/disk I/O errors.

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@8641553a1f (2026-09-11). Data as JSON: /api/errors/d89472c1d4e8209d. Report an issue: GitHub.