{"record":{"id":"49ac0219a4ce3639","repo":"junit-team/junit5","slug":"missing-required-subcommand","errorCode":null,"errorMessage":"Missing required subcommand","messagePattern":"Missing required subcommand","errorType":"validation","errorClass":"ParameterException","httpStatus":null,"severity":"error","filePath":"junit-platform-console/src/main/java/org/junit/platform/console/command/MainCommand.java","lineNumber":80,"sourceCode":"\t@Nullable\n\tCommandResult<?> commandResult;\n\n\tMainCommand(ConsoleTestExecutor.Factory consoleTestExecutorFactory) {\n\t\tthis.consoleTestExecutorFactory = consoleTestExecutorFactory;\n\t}\n\n\t@Override\n\tpublic void run() {\n\t\tif (helpRequested) {\n\t\t\tcommandSpec.commandLine().usage(commandSpec.commandLine().getOut());\n\t\t\tcommandResult = CommandResult.success();\n\t\t}\n\t\telse if (versionRequested) {\n\t\t\tcommandSpec.commandLine().printVersionHelp(commandSpec.commandLine().getOut());\n\t\t\tcommandResult = CommandResult.success();\n\t\t}\n\t\telse {\n\t\t\tthrow new ParameterException(commandSpec.commandLine(), \"Missing required subcommand\");\n\t\t}\n\t}\n\n\t@Override\n\tpublic int getExitCode() {\n\t\treturn requireNonNull(commandResult).getExitCode();\n\t}\n\n\tCommandResult<?> run(String[] args,\n\t\t\t@SuppressWarnings(\"OptionalUsedAsFieldOrParameterType\") Optional<OutputStreamConfig> outputStreamConfig) {\n\t\tCommandLine commandLine = new CommandLine(this) //\n\t\t\t\t.addSubcommand(new DiscoverTestsCommand(consoleTestExecutorFactory)) //\n\t\t\t\t.addSubcommand(new ExecuteTestsCommand(consoleTestExecutorFactory)) //\n\t\t\t\t.addSubcommand(new ListTestEnginesCommand());\n\t\treturn runCommand(commandLine, args, outputStreamConfig);\n\t}\n\n\tprivate static CommandResult<?> runCommand(CommandLine commandLine, String[] args,","sourceCodeStart":62,"sourceCodeEnd":98,"githubUrl":"https://github.com/junit-team/junit5/blob/f070c699a08b5d8393df9afd147af5c5e90bb21b/junit-platform-console/src/main/java/org/junit/platform/console/command/MainCommand.java#L62-L98","documentation":"MainCommand.run() is invoked by picocli when the top-level 'junit' command is called without --help or --version and without any subcommand. Because discover and execute are subcommands, the launcher requires one of them; otherwise it throws a ParameterException that picocli renders as usage plus a non-zero exit code.","triggerScenarios":"Running the console launcher jar with no arguments or with only global options but no subcommand: 'java -jar junit-platform-console-standalone.jar' or '... --disable-banner'. picocli routes to MainCommand.run() and, finding neither help nor version nor a subcommand, raises the error.","commonSituations":"New users running the jar directly; CI scripts that build the args list dynamically and accidentally pass an empty/whitespace arg; wrapper tools that invoke the launcher without specifying 'discover' or 'execute'.","solutions":["Append the intended subcommand: 'execute' to run tests or 'discover' to list discovered tests.","If you only want help/version, pass --help / -h or --version to the top-level command.","Check your wrapper script/CI for an empty or malformed args array that drops the subcommand token."],"exampleFix":"// before\njava -jar junit-platform-console-standalone.jar\n// after\njava -jar junit-platform-console-standalone.jar execute --select-class com.example.MyTests","handlingStrategy":"validation","validationCode":"// In wrapper scripts, ensure a subcommand is present.\nString sub = args.length > 0 ? args[0] : \"\";\nif (!sub.equals(\"discover\") && !sub.equals(\"execute\") && !sub.equals(\"--help\") && !sub.equals(\"-h\") && !sub.equals(\"--version\")) {\n  System.err.println(\"Usage: junit (discover|execute) [options]\");\n  System.exit(2);\n}\n","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Treat the first positional arg as required: it must be a subcommand or a help/version flag.","In CI, echo the full command line (without secrets) on failure so a missing subcommand is obvious.","Pin launcher usage behind a small wrapper script that validates structure."],"tags":["cli","picocli","console-launcher","argument-validation"],"backgroundTag":null,"analyzedSha":"f070c699a08b5d8393df9afd147af5c5e90bb21b","analyzedAt":"2026-08-11T20:31:00.530Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}