nathanmarz/storm · error · IOException
unable to parse
Error message
unable to parse: ${string} What it means
Thrown by ShellProcess.readMessage when a line read from the launched shell subprocess (for a non-JVM language driver) cannot be parsed as JSON via JSONValue.parse. It indicates the child process emitted malformed or unexpected output instead of a valid JSON message, often due to a crashed or misbehaving multilang process writing diagnostic text to stdout.
Solutions
- Inspect the offending string in the message; stray print/debug output from the shell component is the usual culprit.
- Ensure the multilang process writes only JSON messages (or end-of-stream markers) to stdout and sends diagnostics to stderr.
- Check that the shell component's serializer/protocol matches what Storm expects (JSON lines terminated with "end").
- Verify the subprocess did not crash or exit mid-conversation; check ShellProcess subprocess exit status and stderr logs.
Defensive patterns
Strategy: try-catch
When it happens
Trigger: Thrown at storm-core/src/jvm/backtype/storm/utils/ShellProcess.java:86 when the library encounters an invalid state.
Common situations: See trigger scenarios.
Understand the failure class
- Parsing and encoding errors: unexpected token, malformed input — why parsers reject input and how to find the real culprit.
AI-assisted analysis of nathanmarz/storm@cdb116e942 (2026-09-12).
Data as JSON: /api/errors/6560e7c1253f4b5b.
Report an issue: GitHub.
Appendix: source
Thrown at storm-core/src/jvm/backtype/storm/utils/ShellProcess.java:86
public void writeMessage(Object msg) throws IOException {
writeString(JSONValue.toJSONString(msg));
}
private void writeString(String str) throws IOException {
byte[] strBytes = str.getBytes("UTF-8");
processIn.write(strBytes, 0, strBytes.length);
processIn.writeBytes("\nend\n");
processIn.flush();
}
public JSONObject readMessage() throws IOException {
String string = readString();
JSONObject msg = (JSONObject)JSONValue.parse(string);
if (msg != null) {
return msg;
} else {
throw new IOException("unable to parse: " + string);
}
}
public String getErrorsString() {
if(processErrorStream!=null) {
try {
return IOUtils.toString(processErrorStream);
} catch(IOException e) {
return "(Unable to capture error stream)";
}
} else {
return "";
}
}
public void drainErrorStream()
{
try {View on GitHub (pinned to cdb116e942)