{"record":{"id":"269a91560fd0a463","repo":"siyuan-note/siyuan","slug":"mkdir-notebook-crypto-backup-dir-failed-w","errorCode":null,"errorMessage":"mkdir notebook crypto backup dir failed: %w","messagePattern":"mkdir notebook crypto backup dir failed: %w","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"kernel/model/crypto.go","lineNumber":400,"sourceCode":"\t\treturn errors.New(\"cannot generate notebook crypto backup without KEK\")\n\t}\n\tConf.m.Lock()\n\tnc := *Conf.NotebookCrypto // 值拷贝\n\tprepareBackupForWrite(&nc)\n\tnc.KEKMAC = computeKEKMAC(&nc, kek)\n\tif !notebookCryptoConfigurationComplete(&nc) {\n\t\tConf.m.Unlock()\n\t\treturn errors.New(\"cannot save incomplete notebook crypto configuration\")\n\t}\n\tConf.NotebookCrypto.Spec = nc.Spec\n\tConf.NotebookCrypto.BackupID = nc.BackupID\n\tConf.NotebookCrypto.CreatedAt = nc.CreatedAt\n\tConf.NotebookCrypto.Checksum = nc.Checksum\n\tConf.NotebookCrypto.KEKMAC = nc.KEKMAC // 保持 Conf 与备份文件的 KEKMAC 一致\n\tConf.m.Unlock()\n\tbackupPath := dataCryptoBackupPath()\n\tif err := os.MkdirAll(filepath.Dir(backupPath), 0755); err != nil {\n\t\treturn fmt.Errorf(\"mkdir notebook crypto backup dir failed: %w\", err)\n\t}\n\tdata, err := json.Marshal(nc)\n\tif err != nil {\n\t\treturn fmt.Errorf(\"marshal notebook crypto backup failed: %w\", err)\n\t}\n\tif err := atomicWriteFile(backupPath, data); err != nil {\n\t\treturn fmt.Errorf(\"write notebook crypto backup failed: %w\", err)\n\t}\n\treturn nil\n}\n\n// writeNotebookCryptoBackupData 将指定的 NotebookCrypto 写入备份文件（不依赖 Conf.NotebookCrypto）。\n// kek 必须非 nil：在 Checksum 定型后计算 KEKMAC，保证落盘 MAC 与落盘内容一致。\nfunc writeNotebookCryptoBackupData(nc *conf.NotebookCrypto, kek []byte) error {\n\tif kek == nil {\n\t\treturn errors.New(\"cannot generate notebook crypto backup without KEK\")\n\t}\n\tprepareBackupForWrite(nc)","sourceCodeStart":382,"sourceCodeEnd":418,"githubUrl":"https://github.com/siyuan-note/siyuan/blob/8641553a1f07374001902d3ce773285db1292b2d/kernel/model/crypto.go#L382-L418","documentation":"saveNotebookCryptoBackup creates the parent directory of the crypto backup file with os.MkdirAll before writing it; if that fails the error is wrapped with this message. This means the workspace data directory could not be created or is inaccessible, so no backup file can be persisted. The in-memory Conf.NotebookCrypto fields are already updated at this point, but the on-disk backup is missing.","triggerScenarios":"os.MkdirAll(filepath.Dir(dataCryptoBackupPath()), 0755) returns an error during EnableEncryptedNotebook, deriveKEK, or ChangeMasterPassword — e.g. the data directory is read-only, owned by another user, on a full/removable disk, or blocked by sandboxing/antivirus.","commonSituations":"Running SiYuan from a read-only mount or portable disk; workspace moved to a path the process user cannot write; disk full; SELinux/AppArmor or Windows folder permissions blocking directory creation under the data directory.","solutions":["Check and fix filesystem permissions on the workspace data directory so the kernel process can create subdirectories (mkdir/take ownership as needed)","Free disk space if the volume is full, or move the workspace to a writable volume","Check OS-level restrictions (SELinux denials, antivirus, sandbox profiles) that block writes inside the data path"],"exampleFix":"// before: enabling encryption on a read-only workspace\nEnableEncryptedNotebook(...)\n// after: verify writability first\nif err := checkWritableDir(util.DataDir); err != nil {\n    return fmt.Errorf(\"data dir not writable: %w\", err)\n}\nerr := EnableEncryptedNotebook(...)","handlingStrategy":"try-catch","validationCode":"if info, err := os.Stat(util.DataDir); err != nil || !info.IsDir() {\n    // workspace data dir missing or inaccessible\n}\n","typeGuard":null,"tryCatchPattern":"if err := EnableEncryptedNotebook(...); err != nil {\n    var pe *fs.PathError\n    if errors.As(err, &pe) && errors.Is(pe.Err, syscall.EACCES) {\n        // fix permissions on data dir, then retry\n    }\n}\n","preventionTips":["Run the kernel as a user with write access to the workspace","Avoid read-only mounts or removable media for the workspace data directory","Keep antivirus/sandbox rules from blocking writes under the data path","Monitor free disk space on the workspace volume"],"tags":["filesystem","mkdir","backup","permissions","crypto"],"backgroundTag":"mkdir-permission-denied","analyzedSha":"8641553a1f07374001902d3ce773285db1292b2d","analyzedAt":"2026-09-11T16:08:28.414Z","contentChangedAt":"2026-09-11T16:08:28.414Z","schemaVersion":2},"datasetVersion":"2026-09-14T05:17:10.506Z"}