{"record":{"id":"c8ec3266d2d6bed5","repo":"apache/hadoop","slug":"no-data-at-path","errorCode":null,"errorMessage":"No data at path","messagePattern":"No data at path","errorType":"exception","errorClass":"NoRecordException","httpStatus":null,"severity":"warning","filePath":"hadoop-common-project/hadoop-registry/src/main/java/org/apache/hadoop/registry/client/binding/JsonSerDeser.java","lineNumber":100,"sourceCode":"   * will be verified before the JSON parsing takes place; it is a fast-fail\n   * check. If not found, an {@link InvalidRecordException} exception will be\n   * raised\n   * @param path path the data came from\n   * @param bytes byte array\n   * @param marker an optional string which, if set, MUST be present in the\n   * UTF-8 parsed payload.\n   * @return The parsed record\n   * @throws IOException all problems\n   * @throws EOFException not enough data\n   * @throws InvalidRecordException if the JSON parsing failed.\n   * @throws NoRecordException if the data is not considered a record: either\n   * it is too short or it did not contain the marker string.\n   */\n  public T fromBytes(String path, byte[] bytes, String marker)\n      throws IOException {\n    int len = bytes.length;\n    if (len == 0 ) {\n      throw new NoRecordException(path, E_NO_DATA);\n    }\n    if (StringUtils.isNotEmpty(marker) && len < marker.length()) {\n      throw new NoRecordException(path, E_DATA_TOO_SHORT);\n    }\n    String json = new String(bytes, 0, len, StandardCharsets.UTF_8);\n    if (StringUtils.isNotEmpty(marker)\n        && !json.contains(marker)) {\n      throw new NoRecordException(path, E_MISSING_MARKER_STRING + marker);\n    }\n    try {\n      return fromJson(json);\n    } catch (JsonProcessingException e) {\n      throw new InvalidRecordException(path, e.toString(), e);\n    }\n  }\n\n}\n","sourceCodeStart":82,"sourceCodeEnd":118,"githubUrl":"https://github.com/apache/hadoop/blob/2add9630210752f88ceb1bb74eb65e37bf41da8e/hadoop-common-project/hadoop-registry/src/main/java/org/apache/hadoop/registry/client/binding/JsonSerDeser.java#L82-L118","documentation":"JsonSerDeser.fromBytes(path, bytes, marker) deserializes registry znode payloads. A zero-length byte array means the path holds no record at all, so it throws NoRecordException (an IOException subclass) with 'No data at path' — deliberately distinct from InvalidRecordException, which signals corrupt data.","triggerScenarios":"Reading a ZooKeeper znode that was created empty (create without data): placeholder/parent nodes created before the ServiceRecord is written, or a path that exists but has never been populated.","commonSituations":"Registry clients polling a service entry the publisher has not written yet; znodes created by mkdir-style helpers with no payload; tests stubbing ZK reads with empty arrays.","solutions":["Treat NoRecordException as 'record absent', not as corruption: catch it and return Optional.empty() or retry later","Write records atomically — create the znode together with its payload instead of create-then-set-data","Guard reads by znode size: skip nodes whose stat.size is 0 (the pattern RegistryUtils itself uses before reading records)"],"exampleFix":"// before\nbyte[] bytes = registryOps.stat(path) != null ? zkGetData(path) : null;\nServiceRecord r = marshal.fromBytes(path, bytes, marker); // empty node -> NoRecordException\n\n// after\nif (bytes == null || bytes.length == 0) {\n  return Optional.empty();\n}\nServiceRecord r = marshal.fromBytes(path, bytes, marker);","handlingStrategy":"validation","validationCode":"if (bytes == null || bytes.length == 0) {\n  return Optional.empty(); // znode holds no record yet\n}\nreturn Optional.of(marshal.fromBytes(path, bytes, marker));","typeGuard":null,"tryCatchPattern":"try {\n  return Optional.of(marshal.fromBytes(path, bytes, marker));\n} catch (NoRecordException e) {\n  return Optional.empty(); // 'No data at path' — node exists but holds no record\n} catch (InvalidRecordException e) {\n  throw e; // genuinely corrupt payload — do not swallow\n}","preventionTips":["Create znodes together with their payload instead of create-empty-then-set","Check znode stat size before reading (skip size == 0)","Distinguish NoRecordException (absent) from InvalidRecordException (corrupt) in handlers"],"tags":["registry","zookeeper","serialization","empty-data"],"backgroundTag":"empty-payload","analyzedSha":"2add9630210752f88ceb1bb74eb65e37bf41da8e","analyzedAt":"2026-08-22T19:55:07.957Z","schemaVersion":2},"datasetVersion":"2026-08-22T20:17:22.307Z"}