laurent22/joplin · error · Error
Cannot find "%s".
Error message
Cannot find "%s".
What it means
Thrown by `help <command>` when `app().findCommandByName(args.command)` returns falsy. In practice findCommandByName (app.ts:227) returns the cached command, or requires `command-<name>.js`, or throws a typed `notFound` error if the module is missing. The `if (!command)` guard at command-help.ts:66 is defensive and only fires if the require returns a falsy module export — extremely rare in normal operation; the common 'unknown command' case is reported via the notFound error, not this one.
Source
Thrown at packages/app-cli/app/command-help.ts:66
.gui()
.keymap();
const rows = [];
for (let i = 0; i < keymap.length; i++) {
const item = keymap[i];
const keys = item.keys.map((k: string) => (k === ' ' ? '(SPACE)' : k));
rows.push([keys.join(', '), item.command]);
}
cliUtils.printArray(this.stdout.bind(this), rows);
} else if (args.command === 'all') {
const commands = this.allCommands();
const output = commands.map(c => renderCommandHelp(c));
this.stdout(output.join('\n\n'));
} else if (args.command) {
const command = app().findCommandByName(args['command']);
if (!command) throw new Error(_('Cannot find "%s".', args.command));
this.stdout(renderCommandHelp(command, stdoutWidth));
} else {
const commandNames = this.allCommands().map(a => a.name());
this.stdout(_('Type `help [command]` for more information about a command; or type `help all` for the complete usage information.'));
this.stdout('');
this.stdout(_('The possible commands are:'));
this.stdout('');
this.stdout(commandNames.join(', '));
this.stdout('');
this.stdout(_('In any command, a note or notebook can be referred to by title or ID, or using the shortcuts `$n` or `$b` for, respectively, the currently selected note or notebook. `$c` can be used to refer to the currently selected item.'));
this.stdout('');
this.stdout(_('To move from one pane to another, press Tab or Shift+Tab.'));
this.stdout(_('Use the arrows and page up/down to scroll the lists and text areas (including this console).'));
this.stdout(_('To maximise/minimise the console, press "tc".'));
this.stdout(_('To enter command line mode, press ":"'));
this.stdout(_('To exit command line mode, press ESCAPE'));
this.stdout(_('For the list of keyboard shortcuts and config options, type `help keymap`'));View on GitHub (pinned to 2654b33620)
Solutions
- Run `joplin help` (no args) to list the actually-registered command names
- Clear the command metadata cache (remove `~/.config/joplin-dev-desktop/cache.json` / cache db entry keyed 'metadata') and retry
- If developing a custom command, verify `module.exports = Command;` exports a truthy class
- Check for orphaned `command-*.js` files in the app directory that export null/undefined
Example fix
// before joplin help bogusThing // may print "No such command" (notFound) before reaching this guard // after joplin help // lists valid commands joplin help mknote // use a name from the list
Defensive patterns
Strategy: try-catch
Validate before calling
import app from './app';
function commandExists(name: string): boolean {
try {
return !!app().findCommandByName(name);
} catch (e: any) {
if (e?.type === 'notFound') return false;
throw e;
}
}
if (!commandExists(args.command)) {
console.error(`Unknown command "${args.command}". Run \`help\` for the list.`);
} Type guard
const isRegisteredCommand = (name: string): boolean => {
try { return !!app().findCommandByName(name); } catch { return false; }
}; Try / catch
try {
await cli.execCommand(['help', name]);
} catch (e) {
if (e?.type === 'notFound' || /^Cannot find/.test(e.message)) {
// list valid commands as a fallback
await cli.execCommand(['help']);
} else throw e;
} Prevention
- Validate command names against `app().commands()` before calling `help <name>`
- Clear the command metadata cache when developing command files
- Ensure custom command modules `module.exports = Command` with a truthy class
When it happens
Trigger: A command module whose default export is falsy (broken/empty plugin command file loaded into the commands directory); a stale command cache from a downgraded Joplin version.
Common situations: Almost never hit by end users; mainly a developer/extension-author concern when hand-editing command files. Typos in command names hit the 'notFound' error path instead.
Related errors
- Please select a notebook first.
- More than one item match "%s". Please narrow down your query
- Cannot find "%s".
- No notebook selected.
- No notebook has been specified.
AI-assisted analysis of laurent22/joplin@2654b33620 (2026-08-12).
Data as JSON: /api/errors/bf6a4562ba796b59.
Report an issue: GitHub.