{"record":{"id":"f67c59e336e488b3","repo":"laurent22/joplin","slug":"the-command-s-is-only-available-in-gui-mode","errorCode":null,"errorMessage":"The command \"%s\" is only available in GUI mode","messagePattern":"The command \"(.+?)\" is only available in GUI mode","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"packages/app-cli/app/app.ts","lineNumber":284,"sourceCode":"\t\t\thideModalOverlay: () => {},\n\t\t\tstdoutMaxWidth: () => {\n\t\t\t\treturn 100;\n\t\t\t},\n\t\t\tforceRender: () => {},\n\t\t\ttermSaveState: () => {},\n\t\t\ttermRestoreState: () => {},\n\t\t};\n\t}\n\n\tpublic async execCommand(argv: string[]): Promise<void> {\n\t\tif (!argv.length) return this.execCommand(['help']);\n\t\t// reg.logger().debug('execCommand()', argv);\n\t\tconst commandName = argv[0];\n\t\tthis.activeCommand_ = this.findCommandByName(commandName);\n\n\t\tlet outException = null;\n\t\ttry {\n\t\t\tif (this.gui().isDummy() && !this.activeCommand_.supportsUi('cli')) throw new Error(_('The command \"%s\" is only available in GUI mode', this.activeCommand_.name()));\n\t\t\tconst cmdArgs = cliUtils.makeCommandArgs(this.activeCommand_, argv);\n\t\t\tawait this.activeCommand_.action(cmdArgs);\n\t\t} catch (error) {\n\t\t\toutException = error;\n\t\t}\n\t\tthis.activeCommand_ = null;\n\t\tif (outException) throw outException;\n\t}\n\n\tpublic currentCommand() {\n\t\treturn this.activeCommand_;\n\t}\n\n\tpublic async loadKeymaps() {\n\t\tinterface KeyMapItem {\n\t\t\tkeys: string[];\n\t\t\ttype: 'function' | 'prompt';\n\t\t\tcommand: string;","sourceCodeStart":266,"sourceCodeEnd":302,"githubUrl":"https://github.com/laurent22/joplin/blob/2654b33620775080d1d59c552259d41e33dad3d2/packages/app-cli/app/app.ts#L266-L302","documentation":"Each command declares compatibleUis() (BaseCommand default is ['cli','gui']); GUI-only commands like 'search' override it to ['gui']. execCommand checks supportsUi('cli') and, when the app is running with a dummy GUI (pure CLI/scripting mode with no interactive terminal UI) and the command does not support 'cli', it throws 'The command ... is only available in GUI mode'. The message is i18n-translated.","triggerScenarios":"Invoking a GUI-only command (e.g. 'search', 'keymap', 'use') in a non-interactive context — a batch file, stdin pipe, the data API, or any mode where app().gui().isDummy() is true.","commonSituations":"Scripting Joplin via the data API or --batch with a command that only works in the terminal GUI; a command's compatibleUis() was narrowed in a version upgrade.","solutions":["Run the command inside the interactive terminal GUI (launch 'joplin' without --batch).","Use a CLI-compatible alternative command to achieve the same result.","Check command.compatibleUis() before invoking to choose the right path.","If you own the command, add 'cli' to compatibleUis() if the action truly works headless."],"exampleFix":"// before\n//   await app().execCommand(['search', 'foo']); // throws in CLI-only mode\n// after\n//   const cmd = app().findCommandByName('search');\n//   if (!cmd.supportsUi('cli')) {\n//     throw new Error(`Cannot run '${cmd.name()}' without a GUI`);\n//   }","handlingStrategy":"validation","validationCode":"const cmd = app().findCommandByName(name);\nif (app().gui().isDummy() && !cmd.supportsUi('cli')) {\n  throw new Error(`Command '${name}' requires the GUI; run it interactively.`);\n}","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Check command.supportsUi('cli') before invoking commands in scripts or the data API.","Keep batch/API workflows to CLI-compatible commands.","Document which commands are GUI-only in your automation tooling."],"tags":["cli","gui-mode","command-compat","i18n"],"backgroundTag":null,"analyzedSha":"2654b33620775080d1d59c552259d41e33dad3d2","analyzedAt":"2026-08-12T14:26:46.263Z","schemaVersion":2},"datasetVersion":"2026-08-12T18:17:37.767Z"}