{"record":{"id":"e776891796251f9c","repo":"siyuan-note/siyuan","slug":"conf-language-314-e77689","errorCode":null,"errorMessage":"Conf.Language(314)","messagePattern":"Conf\\.Language\\(314\\)","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"kernel/model/import.go","lineNumber":1177,"sourceCode":"\t\tif err = filelock.Copy(assetsDir, dataAssets); err != nil {\n\t\t\tlogging.LogErrorf(\"copy assets from [%s] to [%s] failed: %s\", assetsDir, dataAssets, err)\n\t\t\treturn nil, err\n\t\t}\n\t\tif removeErr := os.RemoveAll(assetsDir); removeErr != nil {\n\t\t\treturn nil, removeErr\n\t\t}\n\t}\n\treturn assetPathMap, nil\n}\n\nfunc writeImportedTree(boxID, syPath, newSyPath, relPath string, data []byte) error {\n\tif IsEncryptedBox(boxID) {\n\t\tHoldBoxReadLock(boxID)\n\t\tdefer ReleaseBoxReadLock(boxID)\n\n\t\tdek, err := GetDEKIfUnlocked(boxID)\n\t\tif err != nil {\n\t\t\treturn errors.New(Conf.Language(314))\n\t\t}\n\t\tdata, err = EncryptFile(boxID, relPath, dek, data)\n\t\tif err != nil {\n\t\t\treturn err\n\t\t}\n\t}\n\tif err := os.WriteFile(syPath, data, 0644); err != nil {\n\t\treturn err\n\t}\n\treturn filelock.Rename(syPath, newSyPath)\n}\n\nfunc validateImportedNotebookIdentities(tmpDataPath string) ([]string, error) {\n\tdirs, err := os.ReadDir(tmpDataPath)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n","sourceCodeStart":1159,"sourceCodeEnd":1195,"githubUrl":"https://github.com/siyuan-note/siyuan/blob/8641553a1f07374001902d3ce773285db1292b2d/kernel/model/import.go#L1159-L1195","documentation":"writeImportedTree writes a document file into the target notebook. If the box is encrypted, it first obtains the notebook's data encryption key with GetDEKIfUnlocked; when the notebook is locked (key unavailable), it returns i18n key 314: \"Please unlock the encrypted notebook first\". The write is deliberately refused instead of silently writing plaintext or failing cryptographically.","triggerScenarios":"importSY0 -> writeImportedTree on an IsEncryptedBox box while GetDEKIfUnlocked fails (user has locked the notebook, or the key/passphrase is unavailable in the current session).","commonSituations":"Importing a .sy.zip into an encrypted notebook that was locked after inactivity or at boot; scripted imports running before the user unlocked the notebook in the UI.","solutions":["Unlock the encrypted notebook in the SiYuan UI (enter its passphrase) and retry the import.","Unlock the notebook programmatically first via the unlock API for that box, then call the import endpoint.","Import into a non-encrypted notebook if unlocking is not possible."],"exampleFix":"// before: POST /api/import/importSY while box locked -> Conf.Language(314)\n// after: unlock first\nawait fetch(\"/api/notebook/unlockEncryptedNotebook\", { method: \"POST\", body: JSON.stringify({ notebook: boxID, password }) });\nawait fetch(\"/api/import/importSY\", { method: \"POST\", body: JSON.stringify({ notebook: boxID, path: zipPath }) });","handlingStrategy":"try-catch","validationCode":"// ensure the notebook is unlocked before import\nawait fetch(\"/api/notebook/lsNotebooks\").then(r => r.json()).then(r => { const b = r.data.notebooks.find(n => n.id === boxID); if (b && b.closed) throw new Error(\"notebook locked\"); });","typeGuard":null,"tryCatchPattern":"try { await importSY(boxID, zipPath); } catch (e) { if (e.msg.includes(\"unlock the encrypted notebook\")) { await unlockEncryptedNotebook(boxID, password); await importSY(boxID, zipPath); } else throw e; }","preventionTips":["Unlock encrypted notebooks before running scripted imports.","Check notebook open/closed state via lsNotebooks before importing.","Disable auto-lock (or re-unlock) for long-running batch imports."],"tags":["encrypted-notebook","encryption-key","locked-notebook","import"],"backgroundTag":"authentication-required","analyzedSha":"8641553a1f07374001902d3ce773285db1292b2d","analyzedAt":"2026-09-11T16:08:28.414Z","contentChangedAt":"2026-09-11T16:08:28.414Z","schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}