{"record":{"id":"5b3283a0db0145ad","repo":"siyuan-note/siyuan","slug":"invalid-imported-notebook-identity-s-w","errorCode":null,"errorMessage":"invalid imported notebook identity [%s]: %w","messagePattern":"invalid imported notebook identity \\[(.+?)\\]: %w","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"critical","filePath":"kernel/model/import.go","lineNumber":1348,"sourceCode":"\t\tbackupPath := filepath.Join(boxDir, \".siyuan\", notebookCryptoBackupFilename)\n\n\t\tvar boxConf *conf.BoxConf\n\t\tif filelock.IsExist(confPath) {\n\t\t\tdata, readErr := filelock.ReadFile(confPath)\n\t\t\tif readErr != nil {\n\t\t\t\treturn nil, fmt.Errorf(\"read imported notebook conf [%s] failed: %w\", boxID, readErr)\n\t\t\t}\n\t\t\tboxConf = conf.NewBoxConf()\n\t\t\tif unmarshalErr := gulu.JSON.UnmarshalJSON(data, boxConf); unmarshalErr != nil {\n\t\t\t\treturn nil, fmt.Errorf(\"parse imported notebook conf [%s] failed: %w\", boxID, unmarshalErr)\n\t\t\t}\n\t\t}\n\n\t\tvar backup *conf.BoxEncryption\n\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}","sourceCodeStart":1330,"sourceCodeEnd":1366,"githubUrl":"https://github.com/siyuan-note/siyuan/blob/9f775e8a12daef8255556097396f9b2739078892/kernel/model/import.go#L1330-L1366","documentation":"validateImportedNotebookIdentities loads the notebook's encryption backup file (.siyuan/<notebookCryptoBackupFilename>) via readBoxEncryptionFile. If that file exists but is invalid (unreadable, malformed, or failing validateBoxEncryption checks), the function returns 'invalid imported notebook identity [%s]' wrapping the cause, because the imported encrypted notebook's key-envelope identity cannot be established and further use would risk unrecoverable data.","triggerScenarios":"ImportData importing a notebook that has an encryption backup file which is corrupt, tampered, an unknown format version, or fails key-derivation parameter validation (e.g. missing/invalid salt, nonce, or algorithm fields).","commonSituations":"1) Partial or failed sync/backup left a truncated backup file. 2) Hand-editing of the encryption backup file. 3) Importing data produced by a newer SiYuan version with an envelope format the current kernel cannot validate (version change). 4) Corruption during archive transfer.","solutions":["Check the kernel log for the wrapped cause from readBoxEncryptionFile/validateBoxEncryption to see which field or check failed.","Restore the notebook's .siyuan encryption backup file from the original workspace, snapshot, or sync history, then retry the import.","Re-export the notebook from the source workspace where it opens successfully, and import that fresh archive.","Do NOT delete or regenerate the encryption backup/salt — per policy, encrypted data must stay recoverable; if the key material is truly lost, access must be restored from the recovery phrase before re-importing."],"exampleFix":null,"handlingStrategy":"validation","validationCode":"const backupPath = path.join(boxDir, '.siyuan', notebookCryptoBackupFilename);\nif (fs.existsSync(backupPath)) {\n  const b = JSON.parse(await fs.promises.readFile(backupPath, 'utf8'));\n  if (!b.salt || !b.nonce || !b.algorithm) throw new Error('incomplete encryption backup');\n}","typeGuard":"function isValidBoxEncryption(v) {\n  return v !== null && typeof v === 'object' && typeof v.salt === 'string' && typeof v.nonce === 'string' && typeof v.algorithm === 'string';\n}","tryCatchPattern":"try {\n  await importData(src);\n} catch (e) {\n  if (/invalid imported notebook identity/.test(e.msg)) {\n    console.error('Restore the notebook\\'s encryption backup from source workspace/history; do not regenerate salts');\n  }\n  throw e;\n}","preventionTips":["Always archive the full .siyuan directory when exporting encrypted notebooks","Never hand-edit or regenerate encryption backup files or MasterSalt","Keep source and target SiYuan versions compatible for envelope formats"],"tags":["encryption","identity","validation","import","siyuan"],"backgroundTag":"checksum-mismatch","analyzedSha":"9f775e8a12daef8255556097396f9b2739078892","analyzedAt":"2026-09-19T03:17:15.984Z","contentChangedAt":"2026-09-19T03:17:15.984Z","schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}