{"record":{"id":"a80652bc70029ea2","repo":"HMCL-dev/HMCL","slug":"bad-exit-code-exitcode","errorCode":null,"errorMessage":"Bad exit code: {exitCode}","messagePattern":"Bad exit code: (.+?)","errorType":"exception","errorClass":"IOException","httpStatus":null,"severity":"error","filePath":"HMCLCore/src/main/java/org/jackhuang/hmcl/util/platform/SystemUtils.java","lineNumber":107,"sourceCode":"    public static <T> T run(List<String> command, ExceptionalFunction<InputStream, T, ?> convert) throws Exception {\n        return run(command, convert, DEFAULT_MAX_WAIT_TIME);\n    }\n\n    public static <T> T run(List<String> command, ExceptionalFunction<InputStream, T, ?> convert, Duration maxWaitTime) throws Exception {\n        Process process = new ProcessBuilder(command)\n                .redirectError(ProcessBuilder.Redirect.DISCARD)\n                .start();\n        try {\n            InputStream inputStream = process.getInputStream();\n            CompletableFuture<T> future = CompletableFuture.supplyAsync(\n                    Lang.wrap(() -> convert.apply(inputStream)),\n                    Schedulers.io());\n\n            if (!process.waitFor(maxWaitTime.toMillis(), TimeUnit.MILLISECONDS))\n                throw new TimeoutException();\n\n            if (process.exitValue() != 0)\n                throw new IOException(\"Bad exit code: \" + process.exitValue());\n\n            return future.get();\n        } finally {\n            if (process.isAlive())\n                process.destroy();\n        }\n    }\n\n    public static boolean supportJVMAttachment() {\n        return Thread.currentThread().getContextClassLoader().getResource(\"com/sun/tools/attach/VirtualMachine.class\") != null;\n    }\n\n    public static void onLogLine(String log) {\n        LOG.info(log);\n    }\n}\n","sourceCodeStart":89,"sourceCodeEnd":124,"githubUrl":"https://github.com/HMCL-dev/HMCL/blob/24702dc5a0214034f4c27166d5fd30cad08cec19/HMCLCore/src/main/java/org/jackhuang/hmcl/util/platform/SystemUtils.java#L89-L124","documentation":"SystemUtils.run runs an external process asynchronously with a timeout and throws IOException 'Bad exit code: <n>' when the process finishes with a nonzero exit value. It indicates the command executed but reported failure.","triggerScenarios":"Calling SystemUtils.run(...) with a command that exits nonzero (bad arguments, script failure) within the max wait time.","commonSituations":"Invoking external tools (git, java, system utilities) that are misconfigured or missing required arguments; scripts failing due to environment differences; underlying program returning failure codes like 1 or 2.","solutions":["Capture and inspect the process stdout/stderr returned by the failed run to see the underlying error.","Run the same command manually in a shell to reproduce and diagnose the nonzero exit.","Fix the command arguments or environment (PATH, permissions) before retrying.","Catch IOException and branch on the exit code if nonzero results are expected/handled."],"exampleFix":"// before\nSystemUtils.run(Arrays.asList(\"git\", \"statusx\"), dir, Duration.ofSeconds(30));\n// after\nSystemUtils.run(Arrays.asList(\"git\", \"status\"), dir, Duration.ofSeconds(30));","handlingStrategy":"try-catch","validationCode":"// verify the external tool exists and arguments are correct first\nif (!new File(\"/usr/bin/git\").canExecute()) throw new IllegalStateException(\"git not installed\");","typeGuard":null,"tryCatchPattern":"try {\n    result = SystemUtils.run(command, dir, timeout);\n} catch (IOException e) {\n    if (e.getMessage().startsWith(\"Bad exit code:\")) {\n        int code = Integer.parseInt(e.getMessage().substring(\"Bad exit code: \".length()));\n        // inspect captured output, handle by code\n    } else throw e;\n}","preventionTips":["Test the exact command in a shell before embedding it.","Capture stdout/stderr so failures are diagnosable.","Check tool availability and PATH before running."],"tags":["process","exit-code","io"],"backgroundTag":"command-not-found","analyzedSha":"24702dc5a0214034f4c27166d5fd30cad08cec19","analyzedAt":"2026-09-10T12:36:46.680Z","contentChangedAt":"2026-09-10T12:36:46.680Z","schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}