{"record":{"id":"e95ea84476ad9196","repo":"karatelabs/karate","slug":"failed-to-start-process","errorCode":null,"errorMessage":"failed to start process: ","messagePattern":"failed to start process: ","errorType":"exception","errorClass":"RuntimeException","httpStatus":null,"severity":"error","filePath":"karate-core/src/main/java/io/karatelabs/process/ProcessHandle.java","lineNumber":163,"sourceCode":"        }\n        try {\n            java.lang.ProcessBuilder pb = new java.lang.ProcessBuilder(config.args());\n            if (config.workingDir() != null) {\n                pb.directory(config.workingDir().toFile());\n            }\n            if (!config.env().isEmpty()) {\n                pb.environment().putAll(config.env());\n            }\n            pb.redirectErrorStream(config.redirectErrorStream());\n            logger.debug(\"starting process: {}\", config.args());\n            this.process = pb.start();\n            this.executor = Executors.newVirtualThreadPerTaskExecutor();\n            LIVE_HANDLES.add(this);\n            startStreamReaders();\n            startExitWaiter();\n            return this;\n        } catch (Exception e) {\n            throw new RuntimeException(\"failed to start process: \" + e.getMessage(), e);\n        }\n    }\n\n    /**\n     * Add a stdout listener. Can be called before or after start().\n     * When redirectErrorStream is true (default), receives both stdout and stderr.\n     */\n    public ProcessHandle onStdOut(Consumer<String> listener) {\n        stdOutListeners.add(listener);\n        return this;\n    }\n\n    /**\n     * Add a stderr listener. Can be called before or after start().\n     * Only receives lines when redirectErrorStream is false.\n     */\n    public ProcessHandle onStdErr(Consumer<String> listener) {\n        stdErrListeners.add(listener);","sourceCodeStart":145,"sourceCodeEnd":181,"githubUrl":"https://github.com/karatelabs/karate/blob/a22eb90246d958d15a47bf436693d0121ad2812d/karate-core/src/main/java/io/karatelabs/process/ProcessHandle.java#L145-L181","documentation":"ProcessHandle.start() wraps any exception thrown while launching the subprocess (ProcessBuilder.start() failures, IO errors setting up streams, executor creation) into 'failed to start process: <message>' with the original exception as cause. The library throws so callers get one clear error when the OS process could not be launched.","triggerScenarios":"start()/fork()/exec with a command that does not exist (IOException: Cannot run program), a workingDir that does not exist or is not a directory, invalid args/env configuration, or OS-level permission denial when exec'ing the binary.","commonSituations":"Wrong path to an executable in fork config, workingDir typo, binary without +x permission, command not installed on CI image, or quoting/argument mistakes in config.args().","solutions":["Read the cause: 'Cannot run program ... No such file or directory' means the executable path is wrong or not installed","Verify the command exists on PATH (or use an absolute path) and is executable (chmod +x)","Check config.workingDir() points to an existing directory","Test the exact args array manually in a shell to reproduce the launch failure"],"exampleFix":"// before\nProcessConfig config = cfg.command(\"mvn test\").workingDir(Path.of(\"./nonexistent\"));\n// after\nProcessConfig config = cfg.command(\"mvn\", \"test\").workingDir(Path.of(\"/absolute/project/dir\"));","handlingStrategy":"try-catch","validationCode":"Path cmd = Path.of(command.split(\" \")[0]);\nif (!java.nio.file.Files.isExecutable(cmd) && findOnPath(command.split(\" \")[0]) == null) {\n    throw new IllegalStateException(\"executable not found: \" + command);\n}\nif (workingDir != null && !java.nio.file.Files.isDirectory(workingDir)) {\n    throw new IllegalStateException(\"workingDir is not a directory: \" + workingDir);\n}","typeGuard":null,"tryCatchPattern":"try {\n    handle.start();\n} catch (RuntimeException e) {\n    if (e.getMessage().startsWith(\"failed to start process:\")) {\n        throw new IllegalStateException(\"check command path/permissions/workingDir\", e.getCause());\n    }\n    throw e;\n}","preventionTips":["Use absolute executable paths in CI images","chmod +x or verify executability before forking","Validate workingDir exists and is a directory","Smoke-test the args array in a plain shell first"],"tags":["process","fork","exec","io"],"backgroundTag":"command-not-found","analyzedSha":"a22eb90246d958d15a47bf436693d0121ad2812d","analyzedAt":"2026-09-12T09:01:00.220Z","contentChangedAt":"2026-09-12T09:01:00.220Z","schemaVersion":2},"datasetVersion":"2026-09-16T19:17:19.609Z"}