prestodb/presto · error · TypeError

no abstract type ColumnHandle

Error message

 no abstract type ColumnHandle 

What it means

This TypeError comes from the to_json overload for std::shared_ptr<ColumnHandle> in the iceberg protocol serializer, which only maps the tag "hive-iceberg" (IcebergColumnHandle). Any handle whose subclass key differs reaches the fallthrough throw reporting that ColumnHandle has no abstract-type mapping for that discriminator.

Source

Thrown at presto-native-execution/presto_cpp/presto_protocol/connector/iceberg/presto_protocol_iceberg.cpp:1160

      "IcebergDeleteTableHandle",
      "Map<String, DeleteFile>",
      "existingDeletionVectors");
}

} // namespace facebook::presto::protocol::iceberg
namespace facebook::presto::protocol::iceberg {
void to_json(json& j, const std::shared_ptr<ColumnHandle>& p) {
  if (p == nullptr) {
    return;
  }
  String type = p->_type;

  if (type == "hive-iceberg") {
    j = *std::static_pointer_cast<IcebergColumnHandle>(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 == "hive-iceberg") {
    std::shared_ptr<IcebergColumnHandle> k =
        std::make_shared<IcebergColumnHandle>();
    j.get_to(*k);
    p = std::static_pointer_cast<ColumnHandle>(k);
    return;
  }

View on GitHub (pinned to 55bb57d202)

Solutions

  1. Ensure the handle is an IcebergColumnHandle with _type set to "hive-iceberg" before serializing in the iceberg layer
  2. Fix the handle's discriminator at construction/deserialization time
  3. Add a to_json branch in presto_protocol_iceberg.cpp if another tag must be supported

Example fix

// before
to_json(j, handle); // handle _type == "hive" -> TypeError in iceberg layer
// after
auto iceberg = std::dynamic_pointer_cast<IcebergColumnHandle>(handle);
if (!iceberg) {
  throw TypeError("expected IcebergColumnHandle for iceberg serialization");
}
to_json(j, std::static_pointer_cast<ColumnHandle>(iceberg));
Defensive patterns

Strategy: type-guard

Validate before calling

std::string tag = handle->getType();
if (tag != "hive-iceberg") {
  throw TypeError("cannot serialize " + tag + " ColumnHandle via iceberg protocol");
}

Type guard

bool isIcebergColumnHandle(const std::shared_ptr<ColumnHandle>& p) {
  return std::dynamic_pointer_cast<IcebergColumnHandle>(p) != nullptr;
}

Try / catch

try {
  to_json(j, columnHandle);
} catch (const TypeError& e) {
  LOG(ERROR) << "Iceberg ColumnHandle serialization failed: " << e.what();
  throw;
}

Prevention

When it happens

Trigger: Calling to_json on a shared_ptr<ColumnHandle> whose getSubclassKey() is not "hive-iceberg" — e.g. a plain HiveColumnHandle serialized through the iceberg protocol layer.

Common situations: Mixing Hive and Iceberg handles when reading a table whose connector changed; plan fragments cached from a different connector; handles built without setting the "hive-iceberg" _type.

Related errors


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