prestodb/presto · error · TypeError
no abstract type FunctionHandle
Error message
no abstract type FunctionHandle
What it means
to_json for shared_ptr<FunctionHandle> serializes via a dispatch on the handle's subclass key and only handles registered values such as '$static' and 'rest'. If the discriminator is anything else, the serializer throws TypeError('<type> no abstract type FunctionHandle ') rather than emitting a partial JSON object. This keeps the wire protocol closed to unknown function-handle types.
Source
Thrown at presto-native-execution/presto_cpp/presto_protocol/core/presto_protocol_core.cpp:133
}
if (type == "native") {
j = *std::static_pointer_cast<NativeFunctionHandle>(p);
return;
}
if (type == "json_file") {
j = *std::static_pointer_cast<SqlFunctionHandle>(p);
return;
}
if (type == "sql_function_handle") {
j = *std::static_pointer_cast<SqlFunctionHandle>(p);
return;
}
if (type == "rest") {
j = *std::static_pointer_cast<RestFunctionHandle>(p);
return;
}
throw TypeError(type + " no abstract type FunctionHandle ");
}
void from_json(const json& j, std::shared_ptr<FunctionHandle>& p) {
String type;
try {
type = p->getSubclassKey(j);
} catch (json::parse_error& e) {
throw ParseError(std::string(e.what()) + " FunctionHandle FunctionHandle");
}
if (type == "$static") {
std::shared_ptr<BuiltInFunctionHandle> k =
std::make_shared<BuiltInFunctionHandle>();
j.get_to(*k);
p = std::static_pointer_cast<FunctionHandle>(k);
return;
}
if (type == "native") {View on GitHub (pinned to 55bb57d202)
Solutions
- Log the subclass key from getSubclassKey to see which type the serializer rejected
- Upgrade presto-native-execution to match the coordinator's function handle types
- Add a to_json branch for the new concrete FunctionHandle in presto_protocol_core.cpp
- Ensure custom FunctionHandle subclasses set _type and override getSubclassKey
Example fix
// before: handle with unset subclass key
auto h = std::make_shared<MyCustomFunctionHandle>(); // never sets _type
to_json(j, std::shared_ptr<FunctionHandle>(h)); // -> TypeError: no abstract type FunctionHandle
// after
auto h = std::make_shared<MyCustomFunctionHandle>();
h->_type = "my-custom";
// plus add in to_json: if (type == "my-custom") { j = *std::static_pointer_cast<MyCustomFunctionHandle>(p); return; } Defensive patterns
Strategy: type-guard
Validate before calling
if (!p || p->getSubclassKey(json::object()).empty()) {
throw std::runtime_error("FunctionHandle has no subclass key; cannot serialize");
} Type guard
bool isRegisteredFunctionHandle(const std::shared_ptr<FunctionHandle>& p) {
static const std::set<std::string> known = {"$static", "rest"};
return p && known.count(p->getSubclassKey(json::object())) > 0;
} Try / catch
try {
to_json(j, p);
} catch (const facebook::presto::protocol::TypeError& e) {
LOG(ERROR) << "Cannot serialize FunctionHandle: " << e.what();
throw;
} Prevention
- Set _type on every concrete FunctionHandle before serialization
- Keep native worker upgrades in step with coordinator FunctionHandle kinds
- Add to_json branches for each new handle type
- Round-trip test serialization for all registered handles
When it happens
Trigger: Serializing a FunctionHandle whose getSubclassKey returns an unregistered value — a custom/unknown function handle class, a default-constructed handle with no type set, or a handle type added in a newer presto version than the native build.
Common situations: Coordinator using a new FunctionKind/handle type not yet supported by presto-native-execution; custom connectors shipping handles the core serializer does not know; tests passing mock handles that never set their '_type'.
Related errors
- no abstract type ColumnHandle
- no abstract type RowExpression
- {type_error} {className} {typeName} {fieldName}
- FunctionHandle FunctionHandle
- NOT_FOUND
AI-assisted analysis of prestodb/presto@55bb57d202 (2026-09-04).
Data as JSON: /api/errors/e1891babf7d5d002.
Report an issue: GitHub.