laurent22/joplin · error · Error
Cannot find "%s".
Error message
Cannot find "%s".
What it means
Thrown by the `search` CLI command when the optional `--notebook` argument names a folder that Folder.loadByTitle cannot resolve in the local database. The command uses the title (not id) to look up the folder that should scope the saved search, so a non-existent or mistyped notebook title aborts before the SEARCH_ADD dispatch. The %s placeholder is replaced with the offending title for display.
Source
Thrown at packages/app-cli/app/command-search.ts:28
}
public override description() {
return _('Searches for the given <pattern> in all the notes.');
}
public override compatibleUis() {
return ['gui'];
}
// eslint-disable-next-line id-denylist -- `notebook` is the CLI argument name declared in usage() and accessed via bracket notation; the identifier appears here only as a type property key
public override async action(args: { pattern: string; notebook?: string }) {
const pattern = args['pattern'];
const folderTitle = args['notebook'];
let folder = null;
if (folderTitle) {
folder = await Folder.loadByTitle(folderTitle);
if (!folder) throw new Error(_('Cannot find "%s".', folderTitle));
}
const searchId = uuid.create();
this.dispatch({
type: 'SEARCH_ADD',
search: {
id: searchId,
title: pattern,
query_pattern: pattern,
query_folder_id: folder ? folder.id : '',
type_: BaseModel.TYPE_SEARCH,
},
});
this.dispatch({
type: 'SEARCH_SELECT',
id: searchId,View on GitHub (pinned to 2654b33620)
Solutions
- Run `ls notebook` / `:notebook list` to confirm the exact stored title and re-run with the correct spelling and case.
- If the notebook lives on another device, run `:sync` first so the folder is replicated into the local database, then retry the search.
- If the title contains spaces or special characters, quote it exactly as shown by the notebook list command.
- Omit `--notebook` entirely to create an unscoped (global) saved search instead.
Example fix
// before
folder = await Folder.loadByTitle(folderTitle);
if (!folder) throw new Error(_('Cannot find "%s".', folderTitle));
// after - hint the user with available titles before failing
const candidates = await Folder.all();
const folder = candidates.find(f => f.title === folderTitle);
if (!folder) throw new Error(_('Cannot find "%s". Known notebooks: %s', folderTitle, candidates.map(f => f.title).join(', '))); Defensive patterns
Strategy: validation
Validate before calling
// Before calling the command, resolve the folder title yourself and show a helpful error.
const folder = await Folder.loadByTitle(notebookTitle);
if (!folder) {
throw new Error(`Notebook "${notebookTitle}" not found. Run \`ls notebook\` first.`);
} Type guard
const isNonEmptyString = (v: unknown): v is string => typeof v === 'string' && v.trim().length > 0;
Try / catch
try {
await app().executeCommand(['search', pattern, '--notebook', notebookTitle]);
} catch (e) {
if (/Cannot find/.test(e.message)) { /* prompt user for correct notebook title */ }
else throw e;
} Prevention
- Always list notebooks before referencing one by title so you copy the exact stored value.
- Sync before referencing a notebook that may only exist on another device.
- Quote notebook titles containing spaces.
When it happens
Trigger: Running `:search <pattern> --notebook <title>` (or the equivalent GUI invocation routed through this command) where `<title>` does not match any Folder.title in the current profile's database. Also triggered if the folder exists only on a sync target that has not yet been pulled locally, or when the title contains whitespace/casing that differs from the stored value.
Common situations: Typos in the notebook name; referencing a notebook created on another device before the first sync completes; duplicate or renamed notebooks where the user recalls the old title; running the command against a fresh/empty profile.
Related errors
- No share found for folder ${folderId}
- No share found for folder ${folder.id}
- No notebook selected.
- No notebook has been specified.
- Cannot find "%s".
AI-assisted analysis of laurent22/joplin@2654b33620 (2026-08-12).
Data as JSON: /api/errors/d27aeba0b685a541.
Report an issue: GitHub.