{"record":{"id":"2666d7469097dce0","repo":"prestodb/presto","slug":"columnhandle-columnhandle-2666d7","errorCode":null,"errorMessage":" ColumnHandle  ColumnHandle","messagePattern":" ColumnHandle  ColumnHandle","errorType":"exception","errorClass":"ParseError","httpStatus":null,"severity":"error","filePath":"presto-native-execution/presto_cpp/presto_protocol/connector/tpcds/presto_protocol_tpcds.cpp","lineNumber":118,"sourceCode":"  if (p == nullptr) {\n    return;\n  }\n  String type = p->_type;\n\n  if (type == \"tpcds\") {\n    j = *std::static_pointer_cast<TpcdsColumnHandle>(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 == \"tpcds\") {\n    std::shared_ptr<TpcdsColumnHandle> k =\n        std::make_shared<TpcdsColumnHandle>();\n    j.get_to(*k);\n    p = std::static_pointer_cast<ColumnHandle>(k);\n    return;\n  }\n\n  throw TypeError(type + \" no abstract type ColumnHandle \");\n}\n} // namespace facebook::presto::protocol::tpcds\nnamespace facebook::presto::protocol::tpcds {\nTpcdsTableHandle::TpcdsTableHandle() noexcept {\n  _type = \"tpcds\";\n}\n","sourceCodeStart":100,"sourceCodeEnd":136,"githubUrl":"https://github.com/prestodb/presto/blob/55bb57d202de3b926896fa966c2c4a44c779634e/presto-native-execution/presto_cpp/presto_protocol/connector/tpcds/presto_protocol_tpcds.cpp#L100-L136","documentation":"presto_protocol's from_json for shared_ptr<ColumnHandle> first extracts the JSON type discriminator via ColumnHandle::getSubclassKey(j). If that call raises a nlohmann json::parse_error (malformed JSON shape, wrong nesting, non-object input), it is rethrown as a facebook::presto::protocol ParseError with 'ColumnHandle ColumnHandle' appended. This lets protocol deserialization fail with a domain-specific error instead of a raw nlohmann exception.","triggerScenarios":"Calling from_json on a JSON fragment that is not a well-formed object where ColumnHandle is expected, e.g. deserializing a malformed plan fragment or task update from the coordinator whose '_type'/subclass key field is absent or the payload is a string/array instead of an object, so getSubclassKey throws json::parse_error.","commonSituations":"Coordinator (Java) and native worker protocol version mismatch causing a differently-shaped ColumnHandle JSON; truncated or hand-edited JSON plan payloads; a custom connector that forgets to serialize the '_type' discriminator field.","solutions":["Log the raw JSON string passed to from_json and run it through a JSON linter to find the malformed section","Verify the coordinator and presto-native-execution protocol versions match (the ColumnHandle wire shape changed between releases)","Check that the custom/connector ColumnHandle serializes the '_type' subclass key field before dispatch","Wrap the deserialization call site in try/catch(ParseError) to surface the offending fragment instead of crashing"],"exampleFix":"// before (raw json fragment, missing object wrapper)\njson j = json::parse(connectorHandleString); // string like '\"tpcds-column\"'\nfrom_json(j, columnHandle);\n// after\njson j = json::parse(connectorHandleString);\nif (!j.is_object()) {\n  throw std::runtime_error(\"ColumnHandle payload must be a JSON object: \" + connectorHandleString);\n}\nfrom_json(j, columnHandle);","handlingStrategy":"try-catch","validationCode":"json j = json::parse(payload);\nif (!j.is_object() || !j.contains(\"_type\")) {\n  throw std::runtime_error(\"ColumnHandle json must be an object with a _type key\");\n}","typeGuard":"bool isDeserializableColumnHandle(const json& j) {\n  return j.is_object() && j.contains(\"_type\") && j[\"_type\"].is_string();\n}","tryCatchPattern":"try {\n  from_json(j, columnHandle);\n} catch (const facebook::presto::protocol::ParseError& e) {\n  LOG(ERROR) << \"ColumnHandle parse failed: \" << e.what() << \" payload=\" << j.dump();\n  throw;\n}","preventionTips":["Always emit a string '_type' discriminator in a JSON object for ColumnHandles","Keep coordinator and native worker protocol versions in sync","Validate plan/split payloads with a JSON schema check before deserialization","Log the raw payload whenever ParseError is caught"],"tags":["json","deserialization","presto-protocol","column-handle"],"backgroundTag":"json-parse-error","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"}