laurent22/joplin · error · Error
Please select a notebook first.
Error message
Please select a notebook first.
What it means
Thrown by `ls` inside the else-branch (pattern is not `/` AND a current notebook exists at the top check). The inner `if (!app().currentFolder())` guard is effectively dead code: the outer condition at line 60 (`pattern === '/' || !app().currentFolder()`) already routed the no-folder case to the folder-listing branch, and no await runs between the two checks, so currentFolder cannot become null in between. If ever hit, it means currentFolder was set to a falsy value mid-call.
Source
Thrown at packages/app-cli/app/command-ls.ts:65
queryOptions.orderByDir = 'ASC';
}
if (options.reverse === true) queryOptions.orderByDir = queryOptions.orderByDir === 'ASC' ? 'DESC' : 'ASC';
queryOptions.caseInsensitive = true;
if (options.type) {
queryOptions.itemTypes = [];
if (options.type.indexOf('n') >= 0) queryOptions.itemTypes.push('note');
if (options.type.indexOf('t') >= 0) queryOptions.itemTypes.push('todo');
}
if (pattern) queryOptions.titlePattern = pattern;
queryOptions.uncompletedTodosOnTop = Setting.value('uncompletedTodosOnTop');
let modelType = null;
if (pattern === '/' || !app().currentFolder()) {
queryOptions.includeConflictFolder = true;
items = await Folder.all(queryOptions);
modelType = Folder.modelType();
} else {
if (!app().currentFolder()) throw new Error(_('Please select a notebook first.'));
items = await Note.previews(app().currentFolder().id, queryOptions);
modelType = Note.modelType();
}
if (options.format && options.format === 'json') {
this.stdout(JSON.stringify(items));
} else {
let hasTodos = false;
for (let i = 0; i < items.length; i++) {
const item = items[i];
if ((item as NoteEntity).is_todo) {
hasTodos = true;
break;
}
}
const seenTitles = [];
const rows = [];View on GitHub (pinned to 2654b33620)
Solutions
- Select a notebook: `joplin use <notebook>` then `joplin ls`
- If you genuinely see this message, file a bug — the upstream guard should have prevented it
- Run `joplin ls /` explicitly to list notebooks when unsure of selection state
Example fix
// before joplin ls // when no notebook is selected, lists folders instead (outer branch) // after joplin use Personal joplin ls // lists notes in Personal
Defensive patterns
Strategy: validation
Validate before calling
import app from './app';
// the throw is effectively unreachable (outer branch handles it), but guard anyway:
function assertNotebookSelectedForLs(): void {
if (!app().currentFolder()) {
throw new Error('Select a notebook first (`use <notebook>`), or run `ls /` to list notebooks.');
}
} Type guard
const hasSelectedNotebook = (): boolean => !!app().currentFolder();
Prevention
- Treat `ls` with no notebook as `ls /` (the outer branch already does this)
- If this message ever appears, report it — it indicates a logic regression
- Use `use <notebook>` to set the active notebook before listing notes
When it happens
Trigger: Not reachable through normal CLI usage because of the upstream short-circuit at line 60. Would only fire if a concurrent `switchCurrentFolder(null)` ran between the outer check and the inner check (single-threaded JS makes this impossible here).
Common situations: Never observed in practice; the error exists as a defensive invariant. Users hitting "no notebook" while listing notes are actually seeing folder output instead (the outer branch).
Related errors
- No notebook selected.
- No notebook has been specified.
- Cannot find "%s".
- No active notebook.
- Cannot find "%s".
AI-assisted analysis of laurent22/joplin@2654b33620 (2026-08-12).
Data as JSON: /api/errors/c1d4a62dd8c0565b.
Report an issue: GitHub.