{"record":{"id":"e1891babf7d5d002","repo":"prestodb/presto","slug":"no-abstract-type-functionhandle","errorCode":null,"errorMessage":" no abstract type FunctionHandle ","messagePattern":" no abstract type FunctionHandle ","errorType":"exception","errorClass":"TypeError","httpStatus":null,"severity":"error","filePath":"presto-native-execution/presto_cpp/presto_protocol/core/presto_protocol_core.cpp","lineNumber":133,"sourceCode":"  }\n  if (type == \"native\") {\n    j = *std::static_pointer_cast<NativeFunctionHandle>(p);\n    return;\n  }\n  if (type == \"json_file\") {\n    j = *std::static_pointer_cast<SqlFunctionHandle>(p);\n    return;\n  }\n  if (type == \"sql_function_handle\") {\n    j = *std::static_pointer_cast<SqlFunctionHandle>(p);\n    return;\n  }\n  if (type == \"rest\") {\n    j = *std::static_pointer_cast<RestFunctionHandle>(p);\n    return;\n  }\n\n  throw TypeError(type + \" no abstract type FunctionHandle \");\n}\n\nvoid from_json(const json& j, std::shared_ptr<FunctionHandle>& p) {\n  String type;\n  try {\n    type = p->getSubclassKey(j);\n  } catch (json::parse_error& e) {\n    throw ParseError(std::string(e.what()) + \" FunctionHandle  FunctionHandle\");\n  }\n\n  if (type == \"$static\") {\n    std::shared_ptr<BuiltInFunctionHandle> k =\n        std::make_shared<BuiltInFunctionHandle>();\n    j.get_to(*k);\n    p = std::static_pointer_cast<FunctionHandle>(k);\n    return;\n  }\n  if (type == \"native\") {","sourceCodeStart":115,"sourceCodeEnd":151,"githubUrl":"https://github.com/prestodb/presto/blob/55bb57d202de3b926896fa966c2c4a44c779634e/presto-native-execution/presto_cpp/presto_protocol/core/presto_protocol_core.cpp#L115-L151","documentation":"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.","triggerScenarios":"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.","commonSituations":"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'.","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"],"exampleFix":"// before: handle with unset subclass key\nauto h = std::make_shared<MyCustomFunctionHandle>(); // never sets _type\nto_json(j, std::shared_ptr<FunctionHandle>(h)); // -> TypeError:  no abstract type FunctionHandle\n// after\nauto h = std::make_shared<MyCustomFunctionHandle>();\nh->_type = \"my-custom\";\n// plus add in to_json: if (type == \"my-custom\") { j = *std::static_pointer_cast<MyCustomFunctionHandle>(p); return; }","handlingStrategy":"type-guard","validationCode":"if (!p || p->getSubclassKey(json::object()).empty()) {\n  throw std::runtime_error(\"FunctionHandle has no subclass key; cannot serialize\");\n}","typeGuard":"bool isRegisteredFunctionHandle(const std::shared_ptr<FunctionHandle>& p) {\n  static const std::set<std::string> known = {\"$static\", \"rest\"};\n  return p && known.count(p->getSubclassKey(json::object())) > 0;\n}","tryCatchPattern":"try {\n  to_json(j, p);\n} catch (const facebook::presto::protocol::TypeError& e) {\n  LOG(ERROR) << \"Cannot serialize FunctionHandle: \" << e.what();\n  throw;\n}","preventionTips":["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"],"tags":["serialization","type-error","presto-protocol","function-handle","subclass-dispatch"],"backgroundTag":"unknown-subclass-type-discriminator","analyzedSha":"55bb57d202de3b926896fa966c2c4a44c779634e","analyzedAt":"2026-09-04T12:50:26.162Z","contentChangedAt":"2026-09-04T12:50:26.162Z","schemaVersion":2},"datasetVersion":"2026-09-11T21:17:09.523Z"}