{"record":{"id":"e7d59de193c01857","repo":"siyuan-note/siyuan","slug":"encrypted-notebook-is-in-an-error-state","errorCode":null,"errorMessage":"encrypted notebook is in an error state","messagePattern":"encrypted notebook is in an error state","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"kernel/model/box_conf_crypto.go","lineNumber":108,"sourceCode":"\t\treturn nil, errors.New(\"notebook configuration is missing\")\n\t}\n\tpersisted := *boxConf\n\tpersisted.BoxCrypt = DeepCopyBoxEncryption(boxConf.BoxCrypt)\n\tif persisted.Encrypted {\n\t\tforgetRuntimeNormalBox(boxID)\n\t}\n\tif !persisted.Encrypted {\n\t\tif IsEncryptedBox(boxID) {\n\t\t\treturn nil, errors.New(\"encrypted notebook cannot be saved as a normal notebook\")\n\t\t}\n\t\treturn &persisted, nil\n\t}\n\tif persisted.BoxCrypt == nil {\n\t\tclearBoxMetadata(&persisted)\n\t\treturn &persisted, nil\n\t}\n\tif GetEncryptedBoxState(boxID) == EncryptedBoxStateError {\n\t\treturn nil, errors.New(\"encrypted notebook is in an error state\")\n\t}\n\n\tif dek, ok := cachedDEKCopy(boxID); ok {\n\t\tdefer zeroAndClear(dek)\n\t\tif err := reuseBoxMetadataIfUnchanged(boxID, &persisted, dek); err != nil {\n\t\t\treturn nil, err\n\t\t}\n\t} else if len(persisted.BoxCrypt.Metadata) == 0 {\n\t\texisting, err := readRawBoxConf(boxID)\n\t\tif err != nil {\n\t\t\treturn nil, err\n\t\t}\n\t\tif existing == nil || existing.BoxCrypt == nil || len(existing.BoxCrypt.Metadata) == 0 {\n\t\t\treturn nil, errors.New(\"encrypted notebook metadata is missing\")\n\t\t}\n\t\tpersisted.BoxCrypt.Metadata = append([]byte(nil), existing.BoxCrypt.Metadata...)\n\t}\n\tif err := validateBoxEncryption(persisted.BoxCrypt); err != nil {","sourceCodeStart":90,"sourceCodeEnd":126,"githubUrl":"https://github.com/siyuan-note/siyuan/blob/8641553a1f07374001902d3ce773285db1292b2d/kernel/model/box_conf_crypto.go#L90-L126","documentation":"prepareBoxConfForSave state guard: the notebook's runtime encrypted-box state is EncryptedBoxStateError (a prior decrypt/verify operation failed), so persisting a new encrypted conf is refused. Writing now could overwrite a suspect envelope and worsen recovery.","triggerScenarios":"Thrown at kernel/model/box_conf_crypto.go:108 when the library encounters an invalid state.","commonSituations":"See trigger scenarios.","solutions":["Resolve the underlying error state first (verify password/key, restore backup)","Retry the save only after the box leaves the error state","Preserve existing data; never regenerate keys to bypass the error"],"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-14T00:17:10.932Z"}