{"record":{"id":"96104b4df6b29b3b","repo":"siyuan-note/siyuan","slug":"notebook-s-is-closed-run-notebook-open-id","errorCode":null,"errorMessage":"notebook [%s] is closed; run `notebook open --id %s` first","messagePattern":"notebook \\[(.+?)\\] is closed; run `notebook open --id (.+?)` first","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"kernel/cli/cmd/notebook.go","lineNumber":92,"sourceCode":"\t\t\treturn nil\n\t\t}\n\n\t\tid, err := model.CreateBox(name)\n\t\tif err != nil {\n\t\t\treturn err\n\t\t}\n\t\tif _, err = model.Mount(id); err != nil {\n\t\t\treturn fmt.Errorf(\"notebook [%s] was created but could not be opened: %w\", id, err)\n\t\t}\n\t\tmodel.AppendPushReloadFiletreeEntry()\n\t\tfmt.Println(id)\n\t\treturn nil\n\t},\n}\n\nfunc formatNotebookWriteError(boxID string, err error) error {\n\tif errors.Is(err, model.ErrBoxClosed) {\n\t\treturn fmt.Errorf(\"notebook [%s] is closed; run `notebook open --id %s` first\", boxID, boxID)\n\t}\n\tif errors.Is(err, model.ErrBoxNotFound) {\n\t\treturn fmt.Errorf(\"notebook [%s] not found\", boxID)\n\t}\n\treturn err\n}\n\nvar notebookRemoveCmd = &cobra.Command{\n\tUse:   \"remove --id <id>\",\n\tShort: \"Remove a notebook\",\n\tRunE: func(cmd *cobra.Command, args []string) error {\n\t\tid, _ := cmd.Flags().GetString(\"id\")\n\t\tif id == \"\" {\n\t\t\treturn fmt.Errorf(\"--id is required\")\n\t\t}\n\n\t\tif dryRun {\n\t\t\tfmt.Printf(\"[dry-run] Would remove notebook %s\\n\", id)","sourceCodeStart":74,"sourceCodeEnd":110,"githubUrl":"https://github.com/siyuan-note/siyuan/blob/251596fc0de2f9528c00c224252fd073a99973f4/kernel/cli/cmd/notebook.go#L74-L110","documentation":"Produced by `formatNotebookWriteError` when a notebook write operation returned `model.ErrBoxClosed`. The helper wraps the sentinel into an actionable message telling the caller to open the notebook first. It is returned by notebook write subcommands (rename, configure, document operations) whose target box is currently closed (unmounted).","triggerScenarios":"Calling a notebook write command against an ID whose box is closed — e.g. after `notebook close`, after a restart that did not auto-mount, or on a box the user manually closed in the GUI. `formatNotebookWriteError` matches the error with `errors.Is(err, model.ErrBoxClosed)` and formats the remediation hint.","commonSituations":"Notebooks are closed by default after certain operations or manually via the GUI; scripts that assume all notebooks are open; operating on a freshly created notebook whose mount failed (see error 238).","solutions":["Open the notebook first: `siyuan notebook open --id <id>`, then retry the write","Confirm the notebook is open with `siyuan notebook list` before scripting writes","If open reports the box not found, the ID is wrong or the box was removed"],"exampleFix":"// before\nsiyuan notebook rename --id 20240101-xyz --name New\n# -> error: notebook [20240101-xyz] is closed; run `notebook open --id 20240101-xyz` first\n// after\nsiyuan notebook open --id 20240101-xyz && siyuan notebook rename --id 20240101-xyz --name New","handlingStrategy":"validation","validationCode":"// Guard notebook writes by checking mount state first:\nboxes, _ := model.ListNotebooks()\nopened := false\nfor _, b := range boxes {\n    if b.ID == boxID && b.Opened { opened = true; break }\n}\nif !opened {\n    if _, err := model.Mount(boxID); err != nil { return err }\n}","typeGuard":null,"tryCatchPattern":"// Match the sentinel before surfacing a generic error:\nif errors.Is(err, model.ErrBoxClosed) {\n    // auto-open then retry, or instruct the user\n    if _, mErr := model.Mount(boxID); mErr == nil { /* retry op */ }\n}","preventionTips":["Run `notebook list` to confirm a box is open before writing to it","Open notebooks explicitly (`notebook open --id`) at the start of any write script","Handle `ErrBoxClosed` by mounting then retrying, not by aborting","A created-but-unmounted notebook (error 238) will trip this on the next write"],"tags":["cli","notebook","state","mount","go","siyuan"],"backgroundTag":null,"analyzedSha":"251596fc0de2f9528c00c224252fd073a99973f4","analyzedAt":"2026-08-12T21:18:37.123Z","schemaVersion":2},"datasetVersion":"2026-08-14T05:17:29.042Z"}