prestodb/presto · error · ParseError

ColumnHandle ColumnHandle

Error message

 ColumnHandle  ColumnHandle

What it means

presto_protocol's from_json for shared_ptr<ColumnHandle> first extracts the JSON type discriminator via ColumnHandle::getSubclassKey(j). If that call raises a nlohmann json::parse_error (malformed JSON shape, wrong nesting, non-object input), it is rethrown as a facebook::presto::protocol ParseError with 'ColumnHandle ColumnHandle' appended. This lets protocol deserialization fail with a domain-specific error instead of a raw nlohmann exception.

Source

Thrown at presto-native-execution/presto_cpp/presto_protocol/connector/tpcds/presto_protocol_tpcds.cpp:118

  if (p == nullptr) {
    return;
  }
  String type = p->_type;

  if (type == "tpcds") {
    j = *std::static_pointer_cast<TpcdsColumnHandle>(p);
    return;
  }

  throw TypeError(type + " no abstract type ColumnHandle ");
}

void from_json(const json& j, std::shared_ptr<ColumnHandle>& p) {
  String type;
  try {
    type = p->getSubclassKey(j);
  } catch (json::parse_error& e) {
    throw ParseError(std::string(e.what()) + " ColumnHandle  ColumnHandle");
  }

  if (type == "tpcds") {
    std::shared_ptr<TpcdsColumnHandle> k =
        std::make_shared<TpcdsColumnHandle>();
    j.get_to(*k);
    p = std::static_pointer_cast<ColumnHandle>(k);
    return;
  }

  throw TypeError(type + " no abstract type ColumnHandle ");
}
} // namespace facebook::presto::protocol::tpcds
namespace facebook::presto::protocol::tpcds {
TpcdsTableHandle::TpcdsTableHandle() noexcept {
  _type = "tpcds";
}

View on GitHub (pinned to 55bb57d202)

Solutions

  1. Log the raw JSON string passed to from_json and run it through a JSON linter to find the malformed section
  2. Verify the coordinator and presto-native-execution protocol versions match (the ColumnHandle wire shape changed between releases)
  3. Check that the custom/connector ColumnHandle serializes the '_type' subclass key field before dispatch
  4. Wrap the deserialization call site in try/catch(ParseError) to surface the offending fragment instead of crashing

Example fix

// before (raw json fragment, missing object wrapper)
json j = json::parse(connectorHandleString); // string like '"tpcds-column"'
from_json(j, columnHandle);
// after
json j = json::parse(connectorHandleString);
if (!j.is_object()) {
  throw std::runtime_error("ColumnHandle payload must be a JSON object: " + connectorHandleString);
}
from_json(j, columnHandle);
Defensive patterns

Strategy: try-catch

Validate before calling

json j = json::parse(payload);
if (!j.is_object() || !j.contains("_type")) {
  throw std::runtime_error("ColumnHandle json must be an object with a _type key");
}

Type guard

bool isDeserializableColumnHandle(const json& j) {
  return j.is_object() && j.contains("_type") && j["_type"].is_string();
}

Try / catch

try {
  from_json(j, columnHandle);
} catch (const facebook::presto::protocol::ParseError& e) {
  LOG(ERROR) << "ColumnHandle parse failed: " << e.what() << " payload=" << j.dump();
  throw;
}

Prevention

When it happens

Trigger: Calling from_json on a JSON fragment that is not a well-formed object where ColumnHandle is expected, e.g. deserializing a malformed plan fragment or task update from the coordinator whose '_type'/subclass key field is absent or the payload is a string/array instead of an object, so getSubclassKey throws json::parse_error.

Common situations: Coordinator (Java) and native worker protocol version mismatch causing a differently-shaped ColumnHandle JSON; truncated or hand-edited JSON plan payloads; a custom connector that forgets to serialize the '_type' discriminator field.

Understand the failure class

Background: JSON parse error: "Unexpected token" / "not valid JSON" / "failed to parse" — what JSON parsers are really complaining about — this error's family across 45 libraries.

Related errors


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