{"record":{"id":"cac525d38a94164d","repo":"siyuan-note/siyuan","slug":"save-encrypted-notebook-conf-failed-w","errorCode":null,"errorMessage":"save encrypted notebook conf failed: %w","messagePattern":"save encrypted notebook conf failed: %w","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"kernel/model/crypto.go","lineNumber":2580,"sourceCode":"\t\t\tcleanupFailedEncryptedBox(createdBoxID)\n\t\t\tid = \"\"\n\t\t}\n\t}()\n\n\tenc, dek, err := WrapNewDEK(id, kek)\n\tif err != nil {\n\t\treturn \"\", err\n\t}\n\n\tbox := &Box{ID: id}\n\tboxConf := box.GetConf()\n\tboxConf.Encrypted = true\n\tboxConf.BoxCrypt = enc\n\tif err = encryptBoxMetadata(id, boxConf, dek); err != nil {\n\t\treturn \"\", fmt.Errorf(\"encrypt notebook metadata failed: %w\", err)\n\t}\n\tif err = box.SaveConf(boxConf); err != nil {\n\t\treturn \"\", fmt.Errorf(\"save encrypted notebook conf failed: %w\", err)\n\t}\n\tif err = writeNotebookCryptBackup(id, enc); err != nil {\n\t\treturn \"\", fmt.Errorf(\"write notebook crypt backup failed: %w\", err)\n\t}\n\t// 回读校验加密配置已落盘，避免写失败后按普通笔记本处理\n\tverifyConf := box.GetConf()\n\tif verifyConf == nil || !verifyConf.Encrypted || verifyConf.BoxCrypt == nil {\n\t\terr = errors.New(\"encrypted notebook metadata verification failed after write\")\n\t\treturn \"\", err\n\t}\n\tmarkRuntimeEncryptedBox(id)\n\tinvalidateEncryptedPublishAccessCache()\n\n\t// 复用刚派生的 DEK 直接开 db + 缓存，省去再次 Argon2id 解锁\n\tcachedDEKsLock.Lock()\n\tif err = sql.OpenEncryptedDB(id, dek); err != nil {\n\t\tcachedDEKsLock.Unlock()\n\t\treturn \"\", err","sourceCodeStart":2562,"sourceCodeEnd":2598,"githubUrl":"https://github.com/siyuan-note/siyuan/blob/251596fc0de2f9528c00c224252fd073a99973f4/kernel/model/crypto.go#L2562-L2598","documentation":"Returned by CreateEncryptedBox when box.SaveConf fails to persist the encrypted notebook's .syconf to disk. The %w wraps the underlying I/O error. The notebook directory was already created and metadata encrypted, but the configuration file couldn't be written — the deferred cleanup (cleanupFailedEncryptedBox) will remove the half-created box.","triggerScenarios":"Disk full, permission denied on the workspace/notebook directory, read-only filesystem, or a file-lock conflict when writing the .syconf file.","commonSituations":"Workspace is on a full or nearly-full disk. User running the kernel without write permission to the workspace directory. Antivirus or file-locking software blocked the write. Network-mounted filesystem with intermittent write failures.","solutions":["Check free disk space on the workspace volume and free space if full.","Verify the kernel process has write permission to the workspace/notebooks directory.","Temporarily disable or exclude the workspace directory in antivirus software and retry."],"exampleFix":null,"handlingStrategy":"try-catch","validationCode":"// Pre-check writable workspace\nif info, err := os.Stat(util.WorkspaceDir); err != nil || info.Mode().Perm()&0200 == 0 {\n    return errors.New(\"workspace directory is not writable\")\n}","typeGuard":null,"tryCatchPattern":"id, err := model.CreateEncryptedBox(name, password)\nif err != nil {\n    if strings.Contains(err.Error(), \"save encrypted notebook conf failed\") {\n        // disk/permission issue — guide user to check space/permissions\n    }\n    return err\n}","preventionTips":["Check disk space and write permissions before initiating notebook creation.","Add antivirus exclusions for the workspace directory.","Avoid running the kernel against network-mounted filesystems with unreliable writes."],"tags":["encryption","notebook-creation","disk-io","filesystem","crypto"],"backgroundTag":null,"analyzedSha":"251596fc0de2f9528c00c224252fd073a99973f4","analyzedAt":"2026-08-12T21:18:37.123Z","schemaVersion":2},"datasetVersion":"2026-08-12T23:17:12.415Z"}