{"record":{"id":"12685746594d395a","repo":"prestodb/presto","slug":"no-abstract-type-columnhandle","errorCode":null,"errorMessage":" no abstract type ColumnHandle ","messagePattern":" no abstract type ColumnHandle ","errorType":"exception","errorClass":"TypeError","httpStatus":null,"severity":"error","filePath":"presto-native-execution/presto_cpp/presto_protocol/connector/arrow_flight/presto_protocol_arrow_flight.cpp","lineNumber":138,"sourceCode":"void from_json(const json& j, ArrowTableHandle& p) {\n  p._type = j[\"@type\"];\n  from_json_key(j, \"schema\", p.schema, \"ArrowTableHandle\", \"String\", \"schema\");\n  from_json_key(j, \"table\", p.table, \"ArrowTableHandle\", \"String\", \"table\");\n}\n} // namespace facebook::presto::protocol::arrow_flight\nnamespace facebook::presto::protocol::arrow_flight {\nvoid to_json(json& j, const std::shared_ptr<ColumnHandle>& p) {\n  if (p == nullptr) {\n    return;\n  }\n  String type = p->_type;\n\n  if (type == \"arrow-flight\") {\n    j = *std::static_pointer_cast<ArrowColumnHandle>(p);\n    return;\n  }\n\n  throw TypeError(type + \" no abstract type ColumnHandle \");\n}\n\nvoid from_json(const json& j, std::shared_ptr<ColumnHandle>& p) {\n  String type;\n  try {\n    type = p->getSubclassKey(j);\n  } catch (json::parse_error& e) {\n    throw ParseError(std::string(e.what()) + \" ColumnHandle  ColumnHandle\");\n  }\n\n  if (type == \"arrow-flight\") {\n    std::shared_ptr<ArrowColumnHandle> k =\n        std::make_shared<ArrowColumnHandle>();\n    j.get_to(*k);\n    p = std::static_pointer_cast<ColumnHandle>(k);\n    return;\n  }\n","sourceCodeStart":120,"sourceCodeEnd":156,"githubUrl":"https://github.com/prestodb/presto/blob/55bb57d202de3b926896fa966c2c4a44c779634e/presto-native-execution/presto_cpp/presto_protocol/connector/arrow_flight/presto_protocol_arrow_flight.cpp#L120-L156","documentation":"This TypeError is thrown by the to_json overload for std::shared_ptr<ColumnHandle> in the arrow_flight protocol serializer. The serializer dispatches on the handle's _type/subclass key string; if the key is anything other than the connector's registered tag (here \"arrow-flight\"), no concrete serialization branch matches and the code reports that the abstract type ColumnHandle has no mapping for that discriminator. It essentially means a ColumnHandle from a different connector (or with a missing/blank type key) was passed into the arrow-flight protocol layer.","triggerScenarios":"Calling to_json on a shared_ptr<ColumnHandle> whose getSubclassKey() returns a string other than \"arrow-flight\" — e.g. a HiveColumnHandle or IcebergColumnHandle routed into arrow-flight JSON conversion, or a deserialized handle whose _type field is empty or corrupt.","commonSituations":"Mixing connector handles across connectors (Hive/Iceberg/TPC-DS handles reused for arrow-flight tables); hand-built ColumnHandle subclasses that never set the _type discriminator; upgrading protocol definitions so the Java-side type tag changed while native code still expects the old tag.","solutions":["Ensure the ColumnHandle passed to serialization is an ArrowColumnHandle whose _type is set to \"arrow-flight\"","Check where the handle is constructed/deserialized and fix the subclass key value so it matches the registered tag","Add the missing to_json branch for the actual type tag in presto_protocol_arrow_flight.cpp if a new subclass is legitimate"],"exampleFix":"// before\nColumnHandle p = someHiveHandle; // _type == \"hive\"\nto_json(j, std::make_shared<HiveColumnHandle>(p)); // arrow_flight to_json -> TypeError\n// after\nif (auto* arrow = dynamic_cast<ArrowColumnHandle*>(handle.get())) {\n  to_json(j, std::shared_ptr<ArrowColumnHandle>(handle, arrow));\n}","handlingStrategy":"type-guard","validationCode":"// before serializing with the arrow_flight protocol layer\nstd::string tag = handle->getType(); // or inspect subclass key\nif (tag != \"arrow-flight\") {\n  throw TypeError(\"cannot serialize \" + tag + \" ColumnHandle via arrow_flight protocol\");\n}","typeGuard":"bool isArrowFlightColumnHandle(const std::shared_ptr<ColumnHandle>& p) {\n  return std::dynamic_pointer_cast<ArrowColumnHandle>(p) != nullptr;\n}","tryCatchPattern":"try {\n  to_json(j, columnHandle);\n} catch (const TypeError& e) {\n  LOG(ERROR) << \"ColumnHandle serialization failed: \" << e.what();\n  throw; // or fall back to the correct connector serializer\n}","preventionTips":["Always construct column handles through the connector's factory so _type is set","Never reuse handles from one connector's plan in another connector's protocol converter","Add unit tests round-tripping every registered ColumnHandle subclass through to_json/from_json","Log the offending subclass key before throwing to speed diagnosis"],"tags":["json-serialization","polymorphic-dispatch","arrow-flight"],"backgroundTag":"unknown-polymorphic-subtype","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"}