{"record":{"id":"33dd07eed1beb17e","repo":"prestodb/presto","slug":"no-abstract-type-rowexpression","errorCode":null,"errorMessage":" no abstract type RowExpression ","messagePattern":" no abstract type RowExpression ","errorType":"exception","errorClass":"TypeError","httpStatus":null,"severity":"error","filePath":"presto-native-execution/presto_cpp/presto_protocol/core/presto_protocol_core.cpp","lineNumber":224,"sourceCode":"  }\n  if (type == \"constant\") {\n    j = *std::static_pointer_cast<ConstantExpression>(p);\n    return;\n  }\n  if (type == \"special\") {\n    j = *std::static_pointer_cast<SpecialFormExpression>(p);\n    return;\n  }\n  if (type == \"lambda\") {\n    j = *std::static_pointer_cast<LambdaDefinitionExpression>(p);\n    return;\n  }\n  if (type == \"variable\") {\n    j = *std::static_pointer_cast<VariableReferenceExpression>(p);\n    return;\n  }\n\n  throw TypeError(type + \" no abstract type RowExpression \");\n}\n\nvoid from_json(const json& j, std::shared_ptr<RowExpression>& p) {\n  String type;\n  try {\n    type = p->getSubclassKey(j);\n  } catch (json::parse_error& e) {\n    throw ParseError(std::string(e.what()) + \" RowExpression  RowExpression\");\n  }\n\n  if (type == \"call\") {\n    std::shared_ptr<CallExpression> k = std::make_shared<CallExpression>();\n    j.get_to(*k);\n    p = std::static_pointer_cast<RowExpression>(k);\n    return;\n  }\n  if (type == \"constant\") {\n    std::shared_ptr<ConstantExpression> k =","sourceCodeStart":206,"sourceCodeEnd":242,"githubUrl":"https://github.com/prestodb/presto/blob/55bb57d202de3b926896fa966c2c4a44c779634e/presto-native-execution/presto_cpp/presto_protocol/core/presto_protocol_core.cpp#L206-L242","documentation":"to_json for shared_ptr<RowExpression> serializes based on the expression's subclass key (e.g. 'call', 'variable', 'constant', ...). When the discriminator is not among the registered values, it throws TypeError('<type> no abstract type RowExpression '). Serialization never emits unknown RowExpression subclasses, protecting the wire protocol.","triggerScenarios":"Serializing a RowExpression whose getSubclassKey yields an unregistered value — a new expression type introduced upstream, a default-constructed expression with no _type, or an IR node the native protocol layer does not map.","commonSituations":"Coordinator (newer Presto) sending row expressions the native side predates; custom expression wrappers in tests; expressions built by native code without setting _type before round-tripping.","solutions":["Print the expression's subclass key to identify the unregistered type","Upgrade presto-native-execution to a version whose RowExpression registry matches the coordinator","Add the missing branch in to_json in presto_protocol_core.cpp for the new expression type","Ensure any custom RowExpression subclass sets _type and implements getSubclassKey"],"exampleFix":"// before: special form without registry entry\nexpr->_type = \"lambda-partial\"; // not dispatched in to_json\nto_json(j, expr); // -> TypeError: lambda-partial no abstract type RowExpression\n// after: use a supported representation or register it\nif (type == \"lambda\") { j = *std::static_pointer_cast<LambdaDefinitionExpression>(p); return; }","handlingStrategy":"type-guard","validationCode":"if (!p || p->getSubclassKey(json::object()).empty()) {\n  throw std::runtime_error(\"RowExpression has no subclass key; cannot serialize\");\n}","typeGuard":"bool isRegisteredRowExpression(const std::shared_ptr<RowExpression>& p) {\n  static const std::set<std::string> known = {\"call\", \"variable\", \"constant\", \"special\", \"lambda\"};\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 RowExpression: \" << e.what();\n  throw;\n}","preventionTips":["Set _type on every expression node before serializing","Track coordinator upgrades that introduce new expression kinds","Add to_json dispatch entries for all supported expression types","Round-trip test expression serialization in CI"],"tags":["serialization","type-error","presto-protocol","row-expression","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"}