{"record":{"id":"9f625d01b549000f","repo":"nathanmarz/storm","slug":"error-when-launching-multilang-subprocess-errorsstring","errorCode":null,"errorMessage":"Error when launching multilang subprocess\n${errorsString}","messagePattern":"Error when launching multilang subprocess\n(.+?)","errorType":"exception","errorClass":"RuntimeException","httpStatus":null,"severity":"critical","filePath":"storm-core/src/jvm/backtype/storm/task/ShellBolt.java","lineNumber":105,"sourceCode":"        _command = command;\n    }\n\n    public void prepare(Map stormConf, TopologyContext context,\n                        final OutputCollector collector) {\n        Object maxPending = stormConf.get(Config.TOPOLOGY_SHELLBOLT_MAX_PENDING);\n        if (maxPending != null) {\n           this._pendingWrites = new LinkedBlockingQueue(((Number)maxPending).intValue());\n        }\n        _rand = new Random();\n        _process = new ShellProcess(_command);\n        _collector = collector;\n\n        try {\n            //subprocesses must send their pid first thing\n            Number subpid = _process.launch(stormConf, context);\n            LOG.info(\"Launched subprocess with pid \" + subpid);\n        } catch (IOException e) {\n            throw new RuntimeException(\"Error when launching multilang subprocess\\n\" + _process.getErrorsString(), e);\n        }\n\n        // reader\n        _readerThread = new Thread(new Runnable() {\n            public void run() {\n                while (_running) {\n                    try {\n                        JSONObject action = _process.readMessage();\n                        if (action == null) {\n                            // ignore sync\n                        }\n\n                        String command = (String) action.get(\"command\");\n                        if(command.equals(\"ack\")) {\n                            handleAck(action);\n                        } else if (command.equals(\"fail\")) {\n                            handleFail(action);\n                        } else if (command.equals(\"error\")) {","sourceCodeStart":87,"sourceCodeEnd":123,"githubUrl":"https://github.com/nathanmarz/storm/blob/cdb116e942666973bc4eaa0df098d5bab82739e7/storm-core/src/jvm/backtype/storm/task/ShellBolt.java#L87-L123","documentation":"ShellBolt.prepare launches the external (multilang, e.g. Python) subprocess and reads its initial pid handshake. If launch() throws IOException, it is rethrown as this RuntimeException including the process's collected stderr (getErrorsString). It means the shell process failed to start or crashed before sending its pid — almost always an error printed by the child interpreter.","triggerScenarios":"The multilang script path is wrong or not executable; the interpreter (e.g. python) is missing or wrong version on the worker host; the script throws an import/parse error on startup (stderr captured in errorsString); required modules not installed in the worker environment; script exits before writing its pid.","commonSituations":"Python script depends on a pip package not installed on Nimbus/worker nodes; deploying to a cluster where the script path in the topology differs from the jar packaging; python2 vs python3 shebang issues; script has a syntax error or fails on import when first executed on the worker.","solutions":["Read the errorsString in the exception message — it contains the subprocess's stderr naming the real problem","Verify the script path and that it is packaged in the topology jar and executable, with a correct shebang (e.g. #!/usr/bin/env python)","SSH into a worker machine and run the script manually to reproduce missing interpreter/modules; install the needed interpreter version and packages on all supervisor nodes","Confirm the script writes its pid first thing ( storm uses ShellProcess launch handshake) — remove any code printing to stdout before the handshake"],"exampleFix":"// before (supervisor missing python deps)\nRuntimeError: Error when launching multilang subprocess\nTraceback: ImportError: No module named redis\n\n// after: on each supervisor node\npip install redis\n# and verify:\npython /path/to/myscript.py  # runs without import errors","handlingStrategy":"validation","validationCode":"# run on every supervisor before deploying:\ntest -x \"$TOPOLOGY_JAR_EXTRACTED_PATH/myscript.py\" && python -c \"import myscript_deps\" \\\n  || echo \"script missing or interpreter/deps not installed\"","typeGuard":null,"tryCatchPattern":"try {\n    builder.setBolt(\"shell\", new ShellBolt(...)).shuffleGrouping(...);\n    submit(topology);\n} catch (RuntimeException e) {\n    if (e.getMessage() != null && e.getMessage().startsWith(\"Error when launching multilang subprocess\")) {\n        LOG.error(\"Subprocess stderr: {}\", e.getMessage()); // errorsString follows the \\n\n    }\n    throw e;\n}","preventionTips":["Include the multilang script in the topology jar and use a resource-relative path","Install the exact interpreter version and all pip/dependency packages on every supervisor node","Run the script standalone on a worker host before deploying","Make sure the script sends its pid first and prints nothing else to stdout before the handshake"],"tags":["storm","multilang","subprocess","python"],"backgroundTag":"file-not-found","analyzedSha":"cdb116e942666973bc4eaa0df098d5bab82739e7","analyzedAt":"2026-09-12T14:30:00.714Z","contentChangedAt":"2026-09-12T14:30:00.714Z","schemaVersion":2},"datasetVersion":"2026-09-16T09:17:16.951Z"}