prestodb/presto · error · OutOfRange
{out_of_range} {className} {typeName} {fieldName}
Error message
{out_of_range} {className} {typeName} {fieldName} What it means
This OutOfRange is thrown when json::out_of_range escapes from_json_key while deserializing a keyed field. In nlohmann json, out_of_range almost always means a required key (via j.at(key)) is missing from the JSON object. The error is re-thrown as OutOfRange with className, typeName, and fieldName appended, identifying which protocol field was missing.
Source
Thrown at presto-native-execution/presto_cpp/presto_protocol/core/presto_protocol_core.h:189
}
}
template <typename T>
void from_json_key(
const json& j,
const char* key,
T& value,
const char* className,
const char* typeName,
const char* fieldName) {
try {
from_json_key(j, key, value);
} catch (json::type_error& e) {
throw TypeError(
std::string(e.what()) + " " + className + " " + typeName + " " +
fieldName);
} catch (json::out_of_range& e) {
throw OutOfRange(
std::string(e.what()) + " " + className + " " + typeName + " " +
fieldName);
}
}
struct KeyedSubclass {
std::string _type; // This member holds the subtype that was serialized.
std::string getSubclassKey(const json& j);
virtual ~KeyedSubclass() {}
};
struct JsonEncodedSubclass : public KeyedSubclass {
std::string getSubclassKey(const json& j);
};
struct Base64EncodedSubclass : public KeyedSubclass {
std::string getSubclassKey(const json& j);View on GitHub (pinned to 55bb57d202)
Solutions
- Read the appended fieldName to identify the missing key, then check why the producer omits it
- Align coordinator and native worker versions
- Make the field optional in the native struct (std::optional + contains() check) if it is legitimately optional
- Validate incoming JSON against the expected schema before deserialization
Example fix
// before: throws when key missing
value = j.at("requiredField").get<std::string>();
// after
value = j.value("requiredField", std::string{}); // or optional + contains check Defensive patterns
Strategy: validation
Validate before calling
// verify required keys exist before from_json
for (const std::string& required : {"type", "requiredField"}) {
if (!j.contains(required)) {
throw std::runtime_error("missing required key: " + required);
}
} Type guard
bool hasKey(const json& j, const std::string& key) {
return j.is_object() && j.contains(key);
} Try / catch
try {
from_json(j, obj);
} catch (const OutOfRange& e) {
// message ends with className typeName fieldName naming the missing key
LOG(ERROR) << "missing JSON key: " << e.what();
throw;
} Prevention
- Prefer j.value(key, default) or contains() checks for optional fields
- Use std::optional in protocol structs for fields that may be absent
- Keep producer and consumer protocol versions in sync
- Validate payloads against the expected schema before deserialization
When it happens
Trigger: from_json on a payload where a mandatory key inside a keyed field is absent — e.g. the coordinator omits a field the native protocol struct requires via j.at().
Common situations: Coordinator and native worker version mismatch (field added on one side only); connector omitting optional fields the native side treats as required; hand-written or filtered JSON payloads.
Related errors
- (JsonMappingException cause message)
- ColumnHandle ColumnHandle
- ColumnHandle ColumnHandle
- FunctionHandle FunctionHandle
- RowExpression RowExpression
AI-assisted analysis of prestodb/presto@55bb57d202 (2026-09-04).
Data as JSON: /api/errors/b18e21e9a94fa49f.
Report an issue: GitHub.