laurent22/joplin · error · Error

Notes can only be created within a notebook.

Error message

Notes can only be created within a notebook.

What it means

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.

Source

Thrown at packages/app-cli/app/command-mktodo.ts:17

import BaseCommand from './base-command';
import app from './app';
import { _ } from '@joplin/lib/locale';
import Note from '@joplin/lib/models/Note';
import { NoteEntity } from '@joplin/lib/services/database/types';

class Command extends BaseCommand {
	public override usage() {
		return 'mktodo <new-todo>';
	}

	public override description() {
		return _('Creates a new to-do.');
	}

	public override async action(args: { 'new-todo': string }) {
		if (!app().currentFolder()) throw new Error(_('Notes can only be created within a notebook.'));

		let note: NoteEntity = {
			title: args['new-todo'],
			parent_id: app().currentFolder().id,
			is_todo: 1,
		};

		note = await Note.save(note);
		void Note.updateGeolocation(note.id);

		app().switchCurrentFolder(app().currentFolder());
	}
}

module.exports = Command;

View on GitHub (pinned to 2654b33620)

Solutions

  1. Create and select a notebook first: `joplin mkbook Tasks && joplin use Tasks`
  2. In scripts, ensure `Setting.value('activeFolderId')` is set before bulk mktodo calls
  3. Use the GUI's `mt` shortcut which operates in a context that already has a notebook

Example fix

// before
joplin mktodo "Buy milk"   // throws

// after
joplin mkbook Tasks
joplin use Tasks
joplin mktodo "Buy milk"
Defensive patterns

Strategy: validation

Validate before calling

import app from './app';

function assertNotebookForCreate(): void {
  if (!app().currentFolder()) {
    throw new Error('No active notebook. Run `mkbook <name>` then `use <name>` before mktodo.');
  }
}

Type guard

const isActiveNotebook = (f: any): f is { id: string } =>
  f !== null && typeof f.id === 'string';

Prevention

When it happens

Trigger: Running `joplin mktodo <title>` with no notebook selected; fresh profile; deleted all notebooks; `activeFolderId` stale.

Common situations: Todo-creation scripts that forget to select a notebook; first-run usage.

Related errors


AI-assisted analysis of laurent22/joplin@2654b33620 (2026-08-12). Data as JSON: /api/errors/a3b382095e7f6230. Report an issue: GitHub.