{"record":{"id":"0dc638c3c67ac24f","repo":"siyuan-note/siyuan","slug":"encrypted-notebook-s-has-no-valid-identity","errorCode":null,"errorMessage":"encrypted notebook [%s] has no valid identity","messagePattern":"encrypted notebook \\[(.+?)\\] has no valid identity","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"critical","filePath":"kernel/model/import.go","lineNumber":1360,"sourceCode":"\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}\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","sourceCodeStart":1342,"sourceCodeEnd":1378,"githubUrl":"https://github.com/siyuan-note/siyuan/blob/9f775e8a12daef8255556097396f9b2739078892/kernel/model/import.go#L1342-L1378","documentation":"For a notebook whose conf.json declares Encrypted=true, validateImportedNotebookIdentities needs a usable BoxEncryption identity: prefer a validated boxConf.BoxCrypt, otherwise fall back to the backup file. If neither is present or valid, it returns 'encrypted notebook [%s] has no valid identity', refusing the import — importing an encrypted notebook without its key envelope would produce permanently unreadable content.","triggerScenarios":"ImportData importing a notebook with conf.json {\"encrypted\": true} but with a missing/nil BoxCrypt field AND a missing or invalid encryption backup file, so no validated identity can be established.","commonSituations":"1) User hand-copied only the .sy files, omitting .siyuan encryption metadata. 2) Archive builder excluded hidden .siyuan directory. 3) Backup file exists but failed validation (see index 1496) so the fallback is nil. 4) Notebook encrypted after export; archive predates encryption.","solutions":["Re-export/re-package the notebook from the source workspace including the full .siyuan directory so BoxCrypt/backup key material is present.","Restore the notebook's encryption backup file from sync history or snapshots, then retry the import.","If the notebook should be plaintext, decrypt it in the source workspace first (with its keys available there), then re-export and import.","Never regenerate MasterSalt or key material to force the import — recover the original keys via the recovery phrase instead."],"exampleFix":null,"handlingStrategy":"validation","validationCode":"const conf = JSON.parse(await fs.promises.readFile(path.join(boxDir, '.siyuan', 'conf.json'), 'utf8'));\nconst hasBackup = fs.existsSync(path.join(boxDir, '.siyuan', notebookCryptoBackupFilename));\nif (conf.encrypted && !conf.boxCrypt && !hasBackup) {\n  throw new Error('encrypted notebook package lacks key material; re-export with .siyuan included');\n}","typeGuard":null,"tryCatchPattern":"try {\n  await importData(src);\n} catch (e) {\n  if (/has no valid identity/.test(e.msg)) {\n    console.error('Re-export including encryption metadata, or restore the backup file / recover keys via recovery phrase');\n  }\n  throw e;\n}","preventionTips":["Include the entire notebook directory (not just .sy files) in transfers of encrypted notebooks","Recover keys via the recovery phrase instead of attempting to regenerate them","Decrypt in the source workspace before exporting if plaintext import is desired"],"tags":["encryption","identity","import","siyuan"],"backgroundTag":"authentication-required","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"}