laurent22/joplin · error · Error

No notebook selected.

Error message

No notebook selected.

What it means

In App.loadItems, when a note pattern contains '*' it is treated as a wildcard title search scoped to a parent notebook via Note.previews(parent.id, ...). The parent is options.parent or app().currentFolder(); if neither is set the call throws 'No notebook selected.'. The message is i18n-translated.

Source

Thrown at packages/app-cli/app/app.ts:103

	public async loadItems(type: FolderOrNoteType, pattern: string, options: { parent?: FolderEntity } | null = null): Promise<(FolderEntity | NoteEntity)[]> {
		if (type === 'folderOrNote') {
			const folders: FolderEntity[] = await this.loadItems(ModelType.Folder, pattern, options);
			if (folders.length) return folders;
			return await this.loadItems(ModelType.Note, pattern, options);
		}

		pattern = pattern ? pattern.toString() : '';

		if (type === ModelType.Folder && (pattern === Folder.conflictFolderTitle() || pattern === Folder.conflictFolderId())) return [Folder.conflictFolder()];

		if (!options) options = {};

		const parent = options.parent ? options.parent : app().currentFolder();
		const ItemClass = BaseItem.itemClass(type);

		if (type === ModelType.Note && pattern.indexOf('*') >= 0) {
			// Handle it as pattern
			if (!parent) throw new Error(_('No notebook selected.'));
			return await Note.previews(parent.id, { titlePattern: pattern });
		} else {
			// Single item
			let item = null;
			if (type === ModelType.Note) {
				if (!parent) throw new Error(_('No notebook has been specified.'));
				item = await (ItemClass as typeof Note).loadFolderNoteByField(parent.id, 'title', pattern);
			} else {
				item = await ItemClass.loadByTitle(pattern);
			}
			if (item) return [item];

			item = await ItemClass.load(pattern); // Load by id
			if (item) return [item];

			if (pattern.length >= 2) {
				return await ItemClass.loadByPartialId(pattern);
			}

View on GitHub (pinned to 2654b33620)

Solutions

  1. Select a notebook first: 'use <notebook>'.
  2. Pass options.parent explicitly when calling loadItems from code.
  3. Create a notebook if none exist: 'mkbook <name>'.

Example fix

// before
//   const notes = await app().loadItems(ModelType.Note, '*todo*'); // throws 'No notebook selected.'
// after
//   await app().switchCurrentFolder(folderId); // or 'use <notebook>' in CLI
//   const notes = await app().loadItems(ModelType.Note, '*todo*');
Defensive patterns

Strategy: validation

Validate before calling

const parent = options?.parent ?? app().currentFolder();
if (pattern.includes('*') && !parent) {
  throw new Error('Select a notebook before using a wildcard note search.');
}

Try / catch

try {
  await app().loadItems(ModelType.Note, pattern);
} catch (e) {
  if (/No notebook selected/.test(e.message)) {
    await app().switchCurrentFolder(defaultFolderId);
  }
}

Prevention

When it happens

Trigger: Running a wildcard note search (e.g. 'ls *' or 'cat *note*') before any notebook is selected, with no options.parent supplied programmatically.

Common situations: First run of a session with no notebook chosen; all notebooks deleted; a script that calls loadItems with a wildcard but does not pass options.parent.

Related errors


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