{"record":{"id":"67d51c67d2af84f7","repo":"siyuan-note/siyuan","slug":"conf-language-316","errorCode":null,"errorMessage":"Conf.Language(316)","messagePattern":"Conf\\.Language\\(316\\)","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"kernel/model/crypto.go","lineNumber":357,"sourceCode":"\tif validErr != nil {\n\t\treturn errors.New(Conf.Language(317))\n\t}\n\tkek := util.DeriveKey(password, nc.MasterSalt, params)\n\tdefer zeroAndClear(kek)\n\tif nc.Checksum != computeBackupChecksum(nc) {\n\t\treturn errors.New(Conf.Language(317))\n\t}\n\tif !verifyKEKMAC(nc, kek) {\n\t\treturn errors.New(Conf.Language(317))\n\t}\n\tdecrypted, dErr := util.DecryptWithAAD(kek, nc.KEKVerifier, []byte(\"siyuan:kek-verifier\"))\n\tif dErr != nil || string(decrypted) != string(kekVerifierMagic) {\n\t\treturn errors.New(Conf.Language(311)) // 主密码错误\n\t}\n\n\t// 校验 KEK 能解密现存笔记本和已删除笔记本历史中的 WrappedDEK，避免导入不匹配的备份。\n\tif !verifyKEKAgainstExistingBoxes(kek, nc) || !verifyKEKAgainstEncryptedHistory(kek, nc) {\n\t\treturn errors.New(Conf.Language(316)) // 密钥不匹配\n\t}\n\n\tnc.KDFParams = params // 确保写回 Conf 的参数已经通过完整校验。\n\tnc.Enabled = true\n\n\t// 先写 backup，再提交 conf；backup 失败时 conf 尚未改变，可重试\n\tif err := writeNotebookCryptoBackupData(nc, kek); err != nil {\n\t\treturn fmt.Errorf(\"failed to persist key backup: %w\", err)\n\t}\n\tConf.m.Lock()\n\t*Conf.NotebookCrypto = *nc\n\tConf.m.Unlock()\n\tConf.Save()\n\tIncSync()\n\treturn nil\n}\n\n// saveNotebookCryptoBackup 把当前 NotebookCrypto（含 MasterSalt/KEKVerifier/KDFParams）备份到 DataDir。","sourceCodeStart":339,"sourceCodeEnd":375,"githubUrl":"https://github.com/siyuan-note/siyuan/blob/8641553a1f07374001902d3ce773285db1292b2d/kernel/model/crypto.go#L339-L375","documentation":"ImportNotebookCryptoBackup compatibility check surfaced as localized message Conf.Language(316) (key mismatch): the password-derived KEK passes the verifier but cannot decrypt the WrappedDEKs of existing notebooks or deleted-notebook history. The backup belongs to a different key lineage, and importing it would orphan existing encrypted data.","triggerScenarios":"Thrown at kernel/model/crypto.go:357 when the library encounters an invalid state.","commonSituations":"See trigger scenarios.","solutions":["Import into the workspace whose keys match the backup lineage","Use the documented recovery flow instead of forcing the import","Preserve the existing envelopes; do not discard keys to proceed"],"exampleFix":null,"handlingStrategy":"validation","validationCode":null,"typeGuard":null,"tryCatchPattern":null,"preventionTips":[],"tags":[],"backgroundTag":null,"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"}