prestodb/presto · error · PrestoException

DECODER_CONVERSION_NOT_SUPPORTED

DECODER_CONVERSION_NOT_SUPPORTED

Error message

could not parse non-value node as '%s' for column '%s'

What it means

ISO8601JsonFieldDecoder.getLong parses ISO-8601 text into the column's timestamp type. If the mapped node is not a scalar value node (object/array), it throws PrestoException DECODER_CONVERSION_NOT_SUPPORTED saying the non-value node can't be parsed. The JSON shape doesn't match the expected ISO-8601 string field.

Source

Thrown at presto-record-decoder/src/main/java/com/facebook/presto/decoder/json/ISO8601JsonFieldDecoder.java:99

        public ISO8601JsonValueProvider(JsonNode value, DecoderColumnHandle columnHandle)
        {
            this.value = value;
            this.columnHandle = columnHandle;
        }

        @Override
        public boolean isNull()
        {
            return value.isMissingNode() || value.isNull();
        }

        @Override
        public long getLong()
        {
            Type columnType = columnHandle.getType();
            if (!value.isValueNode()) {
                throw new PrestoException(
                        DECODER_CONVERSION_NOT_SUPPORTED,
                        format("could not parse non-value node as '%s' for column '%s'", columnType, columnHandle.getName()));
            }

            try {
                String textValue = value.asText();
                if (columnType == TIMESTAMP) {
                    // Equivalent to: ISO_DATE_TIME.parse(textValue, LocalDateTime::from).toInstant(UTC).toEpochMilli();
                    TemporalAccessor parseResult = ISO_DATE_TIME.parse(textValue);
                    return TimeUnit.DAYS.toMillis(parseResult.getLong(EPOCH_DAY)) + parseResult.getLong(MILLI_OF_DAY);
                }
                if (columnType == TIMESTAMP_WITH_TIME_ZONE) {
                    // Equivalent to:
                    // ZonedDateTime dateTime = ISO_OFFSET_DATE_TIME.parse(textValue, ZonedDateTime::from);
                    // packDateTimeWithZone(dateTime.toInstant().toEpochMilli(), getTimeZoneKey(dateTime.getZone().getId()));
                    TemporalAccessor parseResult = ISO_OFFSET_DATE_TIME.parse(textValue);
                    return packDateTimeWithZone(parseResult.getLong(INSTANT_SECONDS) * 1000 + parseResult.getLong(MILLI_OF_SECOND), getTimeZoneKey(ZoneId.from(parseResult).getId()));
                }

View on GitHub (pinned to 55bb57d202)

Solutions

  1. Inspect the JSON node at the mapped field
  2. Fix the column mapping to point at the scalar ISO-8601 string field
  3. Adjust producer to emit the timestamp as a top-level string
  4. Remap or drop the column if the field is inherently structured

Example fix

// before
{"created":{"iso":"2024-01-01T00:00:00Z"}} mapped to created timestamp
// after
{"created":"2024-01-01T00:00:00Z"} or map to created.iso
Defensive patterns

Strategy: validation

Validate before calling

boolean ok = jsonNode.path(fieldName).isValueNode() && jsonNode.path(fieldName).isTextual();

Type guard

static boolean isTextField(JsonNode n) { return n != null && n.isValueNode() && n.isTextual(); }

Try / catch

try { long t = decoder.getLong(); } catch (PrestoException e) { if (DECODER_CONVERSION_NOT_SUPPORTED.equals(e.getErrorCode().getName())) { handleNonValueNode(); } else throw e; }

Prevention

When it happens

Trigger: An ISO8601-formatted timestamp/date column mapped to a JSON field that is an object or array rather than an ISO-8601 string.

Common situations: Producers wrap timestamps in objects like {"date":"..."}; misconfigured column mapping pointing at a nested structure; schema evolution on the topic.

Related errors


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