{"record":{"id":"f513a09bf4e87720","repo":"laurent22/joplin","slug":"no-active-notebook","errorCode":null,"errorMessage":"No active notebook.","messagePattern":"No active notebook\\.","errorType":"validation","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"packages/app-cli/app/command-edit.ts","lineNumber":40,"sourceCode":"\n\t\tconst onFinishedEditing = async () => {\n\t\t\tif (tempFilePath) fs.removeSync(tempFilePath);\n\t\t};\n\n\t\tconst textEditorPath = () => {\n\t\t\tif (Setting.value('editor')) return Setting.value('editor');\n\t\t\tif (process.env.EDITOR) return process.env.EDITOR;\n\t\t\tthrow new Error(_('No text editor is defined. Please set it using `config editor <editor-path>`'));\n\t\t};\n\n\t\ttry {\n\t\t\t// -------------------------------------------------------------------------\n\t\t\t// Load note or create it if it doesn't exist\n\t\t\t// -------------------------------------------------------------------------\n\n\t\t\tconst title = args['note'];\n\n\t\t\tif (!app().currentFolder()) throw new Error(_('No active notebook.'));\n\t\t\tlet note = await app().loadItem(ModelType.Note, title);\n\n\t\t\tthis.encryptionCheck(note);\n\n\t\t\tif (!note) {\n\t\t\t\tconst ok = await this.prompt(_('Note does not exist: \"%s\". Create it?', title));\n\t\t\t\tif (!ok) return;\n\t\t\t\tnote = await Note.save({ title: title, parent_id: app().currentFolder().id });\n\t\t\t\tnote = await Note.load(note.id);\n\t\t\t}\n\n\t\t\t// -------------------------------------------------------------------------\n\t\t\t// Create the file to be edited and prepare the editor program arguments\n\t\t\t// -------------------------------------------------------------------------\n\n\t\t\tlet editorPath = textEditorPath();\n\t\t\tlet editorArgs = splitCommandString(editorPath);\n","sourceCodeStart":22,"sourceCodeEnd":58,"githubUrl":"https://github.com/laurent22/joplin/blob/2654b33620775080d1d59c552259d41e33dad3d2/packages/app-cli/app/command-edit.ts#L22-L58","documentation":"Thrown by the `edit <note>` command when `app().currentFolder()` returns a falsy value. `currentFolder_` is only populated from `Setting.value('activeFolderId')` during CLI startup (app.ts:415-416) or via `switchCurrentFolder`; on a fresh profile, a deleted-last-notebook state, or an empty `activeFolderId`, it stays null. The check fires before `loadItem`, so note lookup is never attempted.","triggerScenarios":"Running `joplin edit <title>` (or the GUI `edit` action) against a profile where `activeFolderId` is empty, references a notebook that no longer exists, or when every notebook has been deleted/moved to trash. Also reachable right after `joplin use <bad-id>` fails silently to switch.","commonSituations":"Fresh Joplin profile with no notebooks created yet; after deleting all notebooks; after switching profiles via `--profile` to an empty one; running edit before ever calling `mkbook`/`use`.","solutions":["Create a notebook first: `joplin mkbook MyNotes`, then select it: `joplin use MyNotes`","Verify a notebook is active by running `joplin ls /` and checking the highlighted/selected entry, or inspect `Setting.value('activeFolderId')`","If a notebook exists but isn't selected, run `joplin use <notebook-title-or-id>` (use short id from `ti`)","If profile is corrupted, check `~/.config/joplin-dev-desktop/settings.json` `activeFolderId` and reset it to a valid folder id"],"exampleFix":"// before\njoplin edit \"Shopping List\"   // throws: No active notebook.\n\n// after\njoplin mkbook Personal\njoplin use Personal\njoplin edit \"Shopping List\"","handlingStrategy":"validation","validationCode":"import app from './app';\nimport { Setting } from '@joplin/lib/models';\n\n// run before invoking edit\nfunction hasActiveNotebook(): boolean {\n  return !!app().currentFolder();\n}\n\n// or, from outside the app process, check the persisted setting:\nfunction activeFolderIdValid(): boolean {\n  return !!Setting.value('activeFolderId');\n}\n\nif (!hasActiveNotebook()) {\n  console.error('No active notebook. Run `mkbook <name>` then `use <name>` first.');\n  process.exit(1);\n}","typeGuard":"import { FolderEntity } from '@joplin/lib/services/database/types';\n\nconst isActiveNotebook = (f: FolderEntity | null): f is FolderEntity =>\n  f !== null && typeof f.id === 'string' && f.id.length > 0;\n\n// usage\nconst folder = app().currentFolder();\nif (!isActiveNotebook(folder)) {\n  throw new Error('precondition: active notebook required');\n}","tryCatchPattern":null,"preventionTips":["In setup scripts, always call `mkbook` + `use` before any note-editing command","After `joplin use <id>`, verify selection by running `joplin ls` (lists notes) rather than `joplin ls /`","Reset `activeFolderId` whenever you reset/restore the profile DB"],"tags":["cli","notebook","state","precondition"],"backgroundTag":null,"analyzedSha":"2654b33620775080d1d59c552259d41e33dad3d2","analyzedAt":"2026-08-12T14:26:46.263Z","schemaVersion":2},"datasetVersion":"2026-08-12T18:17:37.767Z"}