{"record":{"id":"31f31610a7d81cc9","repo":"siyuan-note/siyuan","slug":"notebook-s-has-conflicting-normal-and-encrypted","errorCode":null,"errorMessage":"notebook [%s] has conflicting normal and encrypted identities","messagePattern":"notebook \\[(.+?)\\] has conflicting normal and encrypted identities","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"kernel/model/import.go","lineNumber":1080,"sourceCode":"\t\tif filelock.IsExist(backupPath) {\n\t\t\tbackup, err = readBoxEncryptionFile(backupPath)\n\t\t\tif err != nil {\n\t\t\t\treturn nil, fmt.Errorf(\"invalid imported notebook identity [%s]: %w\", boxID, err)\n\t\t\t}\n\t\t}\n\n\t\tvar boxCrypt *conf.BoxEncryption\n\t\tif boxConf != nil && boxConf.Encrypted {\n\t\t\tif boxConf.BoxCrypt != nil && validateBoxEncryption(boxConf.BoxCrypt) == nil {\n\t\t\t\tboxCrypt = boxConf.BoxCrypt\n\t\t\t} else {\n\t\t\t\tboxCrypt = backup\n\t\t\t}\n\t\t\tif boxCrypt == nil {\n\t\t\t\treturn nil, fmt.Errorf(\"encrypted notebook [%s] has no valid identity\", boxID)\n\t\t\t}\n\t\t} else if boxConf != nil && backup != nil {\n\t\t\treturn nil, fmt.Errorf(\"notebook [%s] has conflicting normal and encrypted identities\", boxID)\n\t\t} else if backup != nil {\n\t\t\tboxCrypt = backup\n\t\t}\n\n\t\tpayloadFound, payloadErr := hasEncryptedNotebookPayloadAtPath(boxDir)\n\t\tif payloadErr != nil {\n\t\t\treturn nil, fmt.Errorf(\"inspect imported notebook [%s] failed: %w\", boxID, payloadErr)\n\t\t}\n\t\tif boxCrypt == nil && payloadFound {\n\t\t\treturn nil, fmt.Errorf(\"imported notebook [%s] contains encrypted payload without identity\", boxID)\n\t\t}\n\t\tif boxCrypt == nil {\n\t\t\tcontinue\n\t\t}\n\n\t\tif err = validateBoxEncryption(boxCrypt); err != nil {\n\t\t\treturn nil, fmt.Errorf(\"invalid imported notebook identity [%s]: %w\", boxID, err)\n\t\t}","sourceCodeStart":1062,"sourceCodeEnd":1098,"githubUrl":"https://github.com/siyuan-note/siyuan/blob/251596fc0de2f9528c00c224252fd073a99973f4/kernel/model/import.go#L1062-L1098","documentation":"Thrown by validateImportedNotebookIdentities when the conf.json explicitly marks the notebook as NOT encrypted (Encrypted: false or absent), but a backup encryption file (notebookCryptoBackupFilename) exists in .siyuan/. This is a contradictory state: the notebook claims to be a normal notebook, yet it carries encrypted-notebook identity artifacts. The import is refused to prevent silently treating encrypted data as plaintext or vice versa.","triggerScenarios":"Calling validateImportedNotebookIdentities where boxConf exists with Encrypted == false, AND backup != nil (backup file exists and was successfully read). The check is at import.go:1079-1080.","commonSituations":"Manual editing of conf.json to remove the Encrypted flag while leaving the backup file. A notebook that was decrypted but the backup file was not cleaned up. Version migration that changed how encryption state is tracked. Export from a SiYuan version that handled encryption state differently.","solutions":["If the notebook is genuinely not encrypted, remove the .siyuan/<backup-filename> from the Data.zip before importing.","If the notebook IS encrypted, fix the conf.json to set Encrypted: true and ensure BoxCrypt is populated.","Re-export from the source SiYuan to get a consistent state.","Manually reconcile the conf.json and backup file to agree on encryption status before importing."],"exampleFix":null,"handlingStrategy":"validation","validationCode":"// Check for identity conflicts before importing\nfunc checkIdentityConflict(tmpDataPath, boxID string) error {\n    confPath := filepath.Join(tmpDataPath, boxID, \".siyuan\", \"conf.json\")\n    backupPath := filepath.Join(tmpDataPath, boxID, \".siyuan\", notebookCryptoBackupFilename)\n    if !filelock.IsExist(confPath) || !filelock.IsExist(backupPath) {\n        return nil\n    }\n    data, _ := filelock.ReadFile(confPath)\n    boxConf := conf.NewBoxConf()\n    if err := gulu.JSON.UnmarshalJSON(data, boxConf); err != nil {\n        return err\n    }\n    if !boxConf.Encrypted {\n        return fmt.Errorf(\"notebook %s: conf says not encrypted but backup exists — conflict\", boxID)\n    }\n    return nil\n}","typeGuard":null,"tryCatchPattern":"encryptedBoxIDs, err := validateImportedNotebookIdentities(tmpDataPath)\nif err != nil {\n    if strings.Contains(err.Error(), \"conflicting normal and encrypted identities\") {\n        // Suggest removing the backup file or fixing conf.json\n        boxID := extractBoxID(err.Error())\n        backupPath := filepath.Join(tmpDataPath, boxID, \".siyuan\", notebookCryptoBackupFilename)\n        if !model.IsEncryptedBox(boxID) {\n            os.Remove(backupPath) // remove stale backup\n        }\n    }\n}","preventionTips":["Re-export Data.zip to ensure consistent encryption state.","Do not manually toggle the Encrypted field in conf.json without also updating/removing the backup file.","If a notebook was decrypted, ensure the export process cleans up backup files.","Inspect the archive's .siyuan/ directory for consistency before importing."],"tags":["encryption","import","data-zip","identity","conflict"],"backgroundTag":null,"analyzedSha":"251596fc0de2f9528c00c224252fd073a99973f4","analyzedAt":"2026-08-12T21:18:37.123Z","schemaVersion":2},"datasetVersion":"2026-08-12T23:17:12.415Z"}