{"record":{"id":"94779857dc84d39e","repo":"siyuan-note/siyuan","slug":"encrypted-notebook-is-locked-please-unlock-it-fir-947798","errorCode":null,"errorMessage":"encrypted notebook is locked, please unlock it first","messagePattern":"encrypted notebook is locked, please unlock it first","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"kernel/mcp/tools/block.go","lineNumber":616,"sourceCode":"\t\t\tsb.WriteString(fmt.Sprintf(\"--- %s ---\\n%s\\n\\n\", id, kd))\n\t\t} else {\n\t\t\tsb.WriteString(fmt.Sprintf(\"--- %s ---\\n(not found)\\n\\n\", id))\n\t\t}\n\t}\n\n\treturn CallToolResult{Content: []ContentItem{{Type: \"text\", Text: sb.String()}}}, nil\n}\n\nfunc beginBlockToolScope(args map[string]any, mutation bool, ids ...string) (boxID string, release func(), err error) {\n\trelease = func() {}\n\tnotebook, _ := args[\"notebook\"].(string)\n\tnotebook = strings.TrimSpace(notebook)\n\tencrypted := notebook != \"\" && model.IsEncryptedBox(notebook)\n\tif encrypted {\n\t\tmodel.HoldBoxReadLock(notebook)\n\t\tif !model.IsBoxUnlocked(notebook) {\n\t\t\tmodel.ReleaseBoxReadLock(notebook)\n\t\t\treturn \"\", release, fmt.Errorf(\"encrypted notebook is locked, please unlock it first\")\n\t\t}\n\t\trelease = func() {\n\t\t\tmodel.ReleaseBoxReadLock(notebook)\n\t\t}\n\t\tboxID = notebook\n\t}\n\n\tfail := func(format string, values ...any) (string, func(), error) {\n\t\trelease()\n\t\treturn \"\", func() {}, fmt.Errorf(format, values...)\n\t}\n\tfor _, id := range ids {\n\t\tif id == \"\" {\n\t\t\tcontinue\n\t\t}\n\t\tqueryBoxID := \"\"\n\t\tif encrypted {\n\t\t\tqueryBoxID = notebook","sourceCodeStart":598,"sourceCodeEnd":634,"githubUrl":"https://github.com/siyuan-note/siyuan/blob/251596fc0de2f9528c00c224252fd073a99973f4/kernel/mcp/tools/block.go#L598-L634","documentation":"`beginBlockToolScope` detected that the target `notebook` is encrypted and is currently locked (no unlocked session). MCP block tools refuse to read or mutate an encrypted notebook until the user unlocks it, so they release the read lock and abort.","triggerScenarios":"Invoking any block tool with a `notebook` argument whose `model.IsEncryptedBox` is true while `model.IsBoxUnlocked` returns false — i.e. the box is encrypted and the user has not supplied the unlock passphrase in this session.","commonSituations":"After a kernel restart the encrypted notebook is locked again and a tool call is made before the user unlocks it via the UI. The `notebook` argument points at an encrypted box the user forgot to unlock.","solutions":["Unlock the encrypted notebook in the SiYuan UI (Settings or the notebook context menu) before retrying the tool call.","Confirm the `notebook` argument is the correct encrypted box ID and that the unlock succeeded.","If the call should target a non-encrypted box, correct the `notebook` argument."],"exampleFix":null,"handlingStrategy":"validation","validationCode":"// Check encryption + unlock state before invoking a block tool.\nif notebook != \"\" && model.IsEncryptedBox(notebook) && !model.IsBoxUnlocked(notebook) {\n    return errors.New(\"unlock the encrypted notebook before calling this tool\")\n}","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Unlock encrypted notebooks in the UI before driving them via MCP.","Verify the notebook ID targets the intended (possibly non-encrypted) box.","Surface unlock-state in your tool orchestration layer."],"tags":["mcp","block","encryption","notebook","authorization"],"backgroundTag":null,"analyzedSha":"251596fc0de2f9528c00c224252fd073a99973f4","analyzedAt":"2026-08-12T21:18:37.123Z","schemaVersion":2},"datasetVersion":"2026-08-12T23:17:12.415Z"}