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

  1. Change the script so it returns an object literal: return { key: value, ... };
  2. If the script computes a single value, wrap it: return { value: computed };
  3. Handle unmatched input by returning an empty object or a sentinel key rather than null.
  4. 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

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


AI-assisted analysis of apache/druid@9b90983fd2 (2026-09-07). Data as JSON: /api/errors/16ad0ccd95b42f89. Report an issue: GitHub.