prestodb/presto · error · PrestoException

ELASTICSEARCH_TYPE_MISMATCH

ELASTICSEARCH_TYPE_MISMATCH

Error message

Expected object for field '%s' of type ROW: %s [%s]

What it means

RowDecoder expects the document field for a Presto ROW (struct) column to be a JSON object (Map). When the retrieved data is not a Map — e.g. an array or scalar — it throws ELASTICSEARCH_TYPE_MISMATCH, since struct fields can only be built from nested objects.

Source

Thrown at presto-elasticsearch/src/main/java/com/facebook/presto/elasticsearch/decoders/RowDecoder.java:60

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

        if (data == null) {
            output.appendNull();
        }
        else if (data instanceof Map) {
            BlockBuilder row = output.beginBlockEntry();
            for (int i = 0; i < decoders.size(); i++) {
                String field = fieldNames.get(i);
                decoders.get(i).decode(hit, () -> getField((Map<String, Object>) data, field), row);
            }
            output.closeEntry();
        }
        else {
            throw new PrestoException(ELASTICSEARCH_TYPE_MISMATCH, format("Expected object for field '%s' of type ROW: %s [%s]", path, data, data.getClass().getSimpleName()));
        }
    }
}

View on GitHub (pinned to 55bb57d202)

Solutions

  1. Make the documents store a nested object: {"address": {"a": "x", "b": "y"}} or reindex accordingly.
  2. If the values are arrays, map the column as ARRAY(ROW(...)) or ARRAY(VARCHAR) instead of ROW.
  3. Fix the table's column definition so it matches the actual document structure.

Example fix

// before
{"address": ["street", "city"]}
// after
{"address": {"street": "...", "city": "..."}}
Defensive patterns

Strategy: validation

Validate before calling

SELECT t.address FROM idx t WHERE t.address IS NOT NULL AND TYPEOF(t.address) <> 'row' LIMIT 1; // detect shape drift

Type guard

function isRowObject(v) { return v !== null && typeof v === 'object' && !Array.isArray(v); }

Try / catch

try { rows = SELECT address FROM "idx"; } catch (PrestoException e) { if (e.getErrorCode().getName().equals("ELASTICSEARCH_TYPE_MISMATCH")) { /* re-declare column as ARRAY or fix docs */ } throw e; }

Prevention

When it happens

Trigger: decode() is invoked for a ROW-typed path where the stored value is an array, string, or number instead of a nested object, e.g. {"address": ["a","b"]} mapped as ROW(a VARCHAR, b VARCHAR).

Common situations: Documents changed shape from object to array of values; nested field flattened by an ingest pipeline; wrong column type declared in the external table definition.

Related errors


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