apache/druid · error · ParseException
JavaScript parsed value [%s] must be in {key: value} format!
Error message
JavaScript parsed value [%s] must be in {key: value} format! What it means
JavaScriptParser.parseToMap applies a user-supplied JavaScript function to the input string and expects the function to return a Map<String, Object> representing {key: value} columns. If the function returns something other than a Map (string, number, array, null), the parser raises this ParseException before the outer catch re-wraps it as 'Unable to parse row'.
Source
Thrown at processing/src/main/java/org/apache/druid/java/util/common/parsers/JavaScriptParser.java:77
};
}
private final Function<Object, Object> fn;
public JavaScriptParser(
final String function
)
{
this.fn = compile(function);
}
@Override
public Map<String, Object> parseToMap(String input)
{
try {
final Object compiled = fn.apply(input);
if (!(compiled instanceof Map)) {
throw new ParseException(input, "JavaScript parsed value [%s] must be in {key: value} format!", input);
}
return (Map) compiled;
}
catch (Exception e) {
throw new ParseException(input, e, "Unable to parse row [%s]", input);
}
}
@Override
public void setFieldNames(Iterable<String> fieldNames)
{
throw new UnsupportedOperationException();
}
@Override
public List<String> getFieldNames()
{View on GitHub (pinned to 9b90983fd2)
Solutions
- Change the script so it returns an object literal: return { key: value, ... };
- If the script computes a single value, wrap it: return { value: computed };
- Handle unmatched input by returning an empty object or a sentinel key rather than null.
- Remove JavaScript usage in favor of native extraction transforms where possible (JS is disabled by default in many deployments).
Example fix
// before
"function(str) { return str.split(',')[0]; }"
// after
"function(str) { return { value: str.split(',')[0] }; }" Defensive patterns
Strategy: validation
Validate before calling
// Validate the JS function's return shape with a test input before deployment:
Object out = fn.apply("sample-input");
if (!(out instanceof Map)) {
throw new IllegalStateException("JS function must return a {key: value} object, got: " + out);
} Type guard
static boolean isJsParserResultValid(final Object compiled) {
return compiled instanceof Map;
} Try / catch
try {
return jsParser.parseToMap(input);
} catch (ParseException e) {
log.warn(e, "JS parser returned non-map for row: %s", input);
return java.util.Collections.emptyMap();
} Prevention
- Always end the JS function with 'return { ... };' object literal.
- Test the script with representative inputs before wiring it into ingestion.
- Return an empty object rather than null for unmatched inputs.
- Prefer native Druid transforms/filters over JavaScript where possible (JS often disabled by config).
When it happens
Trigger: A JavaScript parser/function config whose script ends with something like 'function(str) { return str; }' or returns an array/scalar instead of an object literal, applied via parseToMap.
Common situations: Copy-pasted Druid JS examples that transform values but forget to build the final object; scripts returning JSON.stringify(...) output; scripts returning null on unmatched input.
Related errors
- Illegal segmentId format [%s]
- Unable to parse row [%s]
- Unable to parse row [%s]
- Unable to parse row [%s]
- Unable to parse line.
AI-assisted analysis of apache/druid@9b90983fd2 (2026-09-07).
Data as JSON: /api/errors/16ad0ccd95b42f89.
Report an issue: GitHub.