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

  1. Log the subclass key from getSubclassKey to see which type the serializer rejected
  2. Upgrade presto-native-execution to match the coordinator's function handle types
  3. Add a to_json branch for the new concrete FunctionHandle in presto_protocol_core.cpp
  4. 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

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


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