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
- Ensure the handle is an IcebergColumnHandle with _type set to "hive-iceberg" before serializing in the iceberg layer
- Fix the handle's discriminator at construction/deserialization time
- 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
- Confirm the table's connector before selecting the protocol converter
- Keep iceberg handle construction setting "hive-iceberg" in _type
- Round-trip test iceberg handles in CI
- Reject foreign handles early at the plan-entry boundary
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
- no abstract type ColumnHandle
- no abstract type ColumnHandle
- no abstract type ColumnHandle
- Not a Hive table:
- Not an Iceberg table: ${getSchemaTableName()}
AI-assisted analysis of prestodb/presto@55bb57d202 (2026-09-04).
Data as JSON: /api/errors/5106ff9cf0aa8111.
Report an issue: GitHub.