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

  1. Read the appended fieldName to identify the missing key, then check why the producer omits it
  2. Align coordinator and native worker versions
  3. Make the field optional in the native struct (std::optional + contains() check) if it is legitimately optional
  4. 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

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


AI-assisted analysis of prestodb/presto@55bb57d202 (2026-09-04). Data as JSON: /api/errors/b18e21e9a94fa49f. Report an issue: GitHub.