prestodb/presto · error · PrestoException

ELASTICSEARCH_TYPE_MISMATCH

ELASTICSEARCH_TYPE_MISMATCH

Error message

Expected list of elements for field '%s' of type ARRAY: %s [%s]

What it means

ArrayDecoder decodes a document field declared as ARRAY. If the raw JSON value for the field is present but is not a List (e.g. a single scalar object or a string), it throws PrestoException(ELASTICSEARCH_TYPE_MISMATCH). Elasticsearch does not have a true array type — a field can hold a single value in some documents and an array in others — so this fires when a document stores a non-list value for a field mapped as an array.

Source

Thrown at presto-elasticsearch/src/main/java/com/facebook/presto/elasticsearch/decoders/ArrayDecoder.java:53

        this.path = requireNonNull(path, "path is null");
        this.elementDecoder = elementDecoder;
    }

    @Override
    public void decode(Hit hit, Supplier<Object> getter, BlockBuilder output)
    {
        Object data = getter.get();

        if (data == null) {
            output.appendNull();
        }
        else if (data instanceof List) {
            BlockBuilder array = output.beginBlockEntry();
            ((List) data).forEach(element -> elementDecoder.decode(hit, () -> element, array));
            output.closeEntry();
        }
        else {
            throw new PrestoException(ELASTICSEARCH_TYPE_MISMATCH, format("Expected list of elements for field '%s' of type ARRAY: %s [%s]", path, data, data.getClass().getSimpleName()));
        }
    }
}

View on GitHub (pinned to 55bb57d202)

Solutions

  1. Fix the offending documents to store arrays for the field, or wrap the scalar in an array during ingestion.
  2. Change the Presto column type to match the actual data (e.g. VARCHAR/ROW instead of ARRAY).
  3. Set the connector's text-field/mapping config or use elasticsearch.index mappings to make the field consistently an array.
  4. Use a fallback/COALESCE view if you cannot clean the data (requires connector-level handling).

Example fix

// before (document)
{ "tags": "red" }
// after
{ "tags": ["red"] }
Defensive patterns

Strategy: validation

Validate before calling

// ensure every document stores an array for the field
curl -s 'localhost:9200/<index>/_search?q=tags:*&_source=tags&size=100' \
  | jq '[.hits.hits[]._source.tags | select(type != "array")]'
# empty result means all values are arrays

Try / catch

try {
    rs = stmt.executeQuery("SELECT tags FROM es.default.idx");
} catch (PrestoException e) {
    if (e.getErrorCode().getName().equals("ELASTICSEARCH_TYPE_MISMATCH")) {
        log.warn("Non-array value in array field; reindex offending documents");
    } else { throw e; }
}

Prevention

When it happens

Trigger: Index contains documents where the ARRAY-typed field holds a single JSON object/string instead of an array; thrown during decode while reading rows in ScanQueryPageSource.

Common situations: Schema declared as ARRAY<...> but documents written with a scalar value for that field; dynamic mapping inferred differently per document; data ingestion pipeline changed shape mid-stream.

Related errors


AI-assisted analysis of prestodb/presto@55bb57d202 (2026-09-04). Data as JSON: /api/errors/8de632a9d5110e08. Report an issue: GitHub.