laurent22/joplin · warning · Error

Shortcuts are not available in CLI mode.

Error message

Shortcuts are not available in CLI mode.

What it means

Thrown by `help shortcuts` (or `help keymap`) when the GUI is a dummy. The CLI runs in two modes: interactive GUI (`app-gui.ts`, real keymap) and one-shot CLI (`dummyGui()`, `isDummy() === true`). Keymaps only exist in the interactive GUI; the one-shot CLI has no keymap, so printing one is impossible. The message above the throw still helpfully points to the online docs URL.

Solutions

  1. Visit the URL printed just before the throw: https://joplinapp.org/help/apps/terminal#shortcuts
  2. Launch the interactive terminal GUI (run `joplin` with no command args) and press the relevant keys, then run `:help shortcuts` inside it
  3. If you need keymap data programmatically, read `<profileDir>/keymap.json` directly (falling back to defaults from app.ts:loadKeymaps)

Example fix

// before (one-shot CLI)
joplin help shortcuts   // throws: Shortcuts are not available in CLI mode.

// after
# option A: read the docs URL the command prints
# option B: read the keymap file directly
cat ~/.config/joplin-dev-desktop/keymap.json
# option C: launch interactive mode (no command arg) and run :help shortcuts
Defensive patterns

Strategy: validation

Validate before calling

import app from './app';

function assertInteractiveGuiForShortcuts(): void {
  if (!app().hasGui() || app().gui().isDummy()) {
    throw new Error('Shortcuts/keymap require the interactive terminal GUI. See https://joplinapp.org/help/apps/terminal#shortcuts');
  }
}

// or read the keymap file directly instead of going through `help keymap`:
// `${Setting.value('profileDir')}/keymap.json`

Type guard

const hasRealKeymap = (): boolean =>
  app().hasGui() && !app().gui().isDummy() && typeof app().gui().keymap === 'function';

Prevention

When it happens

Trigger: Running `joplin help shortcuts` or `joplin help keymap` as a one-shot CLI invocation (argv passed to the binary). The check `app().gui().isDummy()` is true in this path (app.ts:413 sets `this.gui_ = this.dummyGui()`).

Common situations: CI/scripted calls to `joplin help keymap` expecting structured output; users exploring the CLI from a non-interactive shell.

Related errors


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

Appendix: source

Thrown at packages/app-cli/app/command-help.ts:44

		output.sort((a, b) => (a.name() < b.name() ? -1 : +1));

		return output;
	}

	public override async action(args: { command?: string }) {
		const stdoutWidth = app().commandStdoutMaxWidth();

		if (args.command === 'shortcuts' || args.command === 'keymap') {
			this.stdout(_('For information on how to customise the shortcuts please visit %s', 'https://joplinapp.org/help/apps/terminal#shortcuts'));
			this.stdout('');

			if (
				app()
					.gui()
					.isDummy()
			) {
				throw new Error(_('Shortcuts are not available in CLI mode.'));
			}

			const keymap = app()
				.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));

View on GitHub (pinned to 2654b33620)