{"record":{"id":"a3b382095e7f6230","repo":"laurent22/joplin","slug":"notes-can-only-be-created-within-a-notebook-a3b382","errorCode":null,"errorMessage":"Notes can only be created within a notebook.","messagePattern":"Notes can only be created within a notebook\\.","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"packages/app-cli/app/command-mktodo.ts","lineNumber":17,"sourceCode":"import BaseCommand from './base-command';\nimport app from './app';\nimport { _ } from '@joplin/lib/locale';\nimport Note from '@joplin/lib/models/Note';\nimport { NoteEntity } from '@joplin/lib/services/database/types';\n\nclass Command extends BaseCommand {\n\tpublic override usage() {\n\t\treturn 'mktodo <new-todo>';\n\t}\n\n\tpublic override description() {\n\t\treturn _('Creates a new to-do.');\n\t}\n\n\tpublic override async action(args: { 'new-todo': string }) {\n\t\tif (!app().currentFolder()) throw new Error(_('Notes can only be created within a notebook.'));\n\n\t\tlet note: NoteEntity = {\n\t\t\ttitle: args['new-todo'],\n\t\t\tparent_id: app().currentFolder().id,\n\t\t\tis_todo: 1,\n\t\t};\n\n\t\tnote = await Note.save(note);\n\t\tvoid Note.updateGeolocation(note.id);\n\n\t\tapp().switchCurrentFolder(app().currentFolder());\n\t}\n}\n\nmodule.exports = Command;\n","sourceCodeStart":1,"sourceCodeEnd":33,"githubUrl":"https://github.com/laurent22/joplin/blob/2654b33620775080d1d59c552259d41e33dad3d2/packages/app-cli/app/command-mktodo.ts#L1-L33","documentation":"Thrown by `mktodo <new-todo>` when `app().currentFolder()` is falsy. Identical precondition to mknote; todos are notes with `is_todo: 1` and likewise require a parent notebook. The command builds the entity with `parent_id: app().currentFolder().id`, so a null folder would NPE without this guard.","triggerScenarios":"Running `joplin mktodo <title>` with no notebook selected; fresh profile; deleted all notebooks; `activeFolderId` stale.","commonSituations":"Todo-creation scripts that forget to select a notebook; first-run usage.","solutions":["Create and select a notebook first: `joplin mkbook Tasks && joplin use Tasks`","In scripts, ensure `Setting.value('activeFolderId')` is set before bulk mktodo calls","Use the GUI's `mt` shortcut which operates in a context that already has a notebook"],"exampleFix":"// before\njoplin mktodo \"Buy milk\"   // throws\n\n// after\njoplin mkbook Tasks\njoplin use Tasks\njoplin mktodo \"Buy milk\"","handlingStrategy":"validation","validationCode":"import app from './app';\n\nfunction assertNotebookForCreate(): void {\n  if (!app().currentFolder()) {\n    throw new Error('No active notebook. Run `mkbook <name>` then `use <name>` before mktodo.');\n  }\n}","typeGuard":"const isActiveNotebook = (f: any): f is { id: string } =>\n  f !== null && typeof f.id === 'string';","tryCatchPattern":null,"preventionTips":["Ensure a notebook is selected before bulk todo creation","In scripts, pre-create a Tasks-style notebook","Reuse the same precondition helper as mknote — the requirement is identical"],"tags":["cli","mktodo","notebook","precondition"],"backgroundTag":null,"analyzedSha":"2654b33620775080d1d59c552259d41e33dad3d2","analyzedAt":"2026-08-12T14:26:46.263Z","schemaVersion":2},"datasetVersion":"2026-08-12T18:17:37.767Z"}