{"record":{"id":"dd49d8e243b36614","repo":"apache/hadoop","slug":"unknown-operation-operation-name","errorCode":null,"errorMessage":"Unknown operation ${operation.name()}","messagePattern":"Unknown operation (.+?)","errorType":"exception","errorClass":"IOException","httpStatus":null,"severity":"warning","filePath":"hadoop-hdfs-project/hadoop-hdfs-client/src/main/java/org/apache/hadoop/hdfs/web/WebHdfsFileSystem.java","lineNumber":1972,"sourceCode":"\n  private boolean isGetFileBlockLocationsException(RemoteException e) {\n    return e.getMessage() != null && e.getMessage().contains(\"Invalid value for webhdfs parameter\")\n        && e.getMessage().contains(GetOpParam.Op.GETFILEBLOCKLOCATIONS.toString());\n  }\n\n  private BlockLocation[] getFileBlockLocations(final GetOpParam.Op operation,\n      final Path p, final long offset, final long length) throws IOException {\n    return new FsPathResponseRunner<BlockLocation[]>(operation, p,\n        new OffsetParam(offset), new LengthParam(length)) {\n      @Override\n      BlockLocation[] decodeResponse(Map<?, ?> json) throws IOException {\n        switch (operation) {\n        case GETFILEBLOCKLOCATIONS:\n          return JsonUtilClient.toBlockLocationArray(json);\n        case GET_BLOCK_LOCATIONS:\n          return DFSUtilClient.locatedBlocks2Locations(JsonUtilClient.toLocatedBlocks(json));\n        default:\n          throw new IOException(\"Unknown operation \" + operation.name());\n        }\n      }\n    }.run();\n  }\n\n  @Override\n  public Path getTrashRoot(Path path) {\n    statistics.incrementReadOps(1);\n    storageStatistics.incrementOpCounter(OpType.GET_TRASH_ROOT);\n\n    final HttpOpParam.Op op = GetOpParam.Op.GETTRASHROOT;\n    try {\n      String strTrashPath = new FsPathResponseRunner<String>(op, path) {\n        @Override\n        String decodeResponse(Map<?, ?> json) throws IOException {\n          return JsonUtilClient.getPath(json);\n        }\n      }.run();","sourceCodeStart":1954,"sourceCodeEnd":1990,"githubUrl":"https://github.com/apache/hadoop/blob/2add9630210752f88ceb1bb74eb65e37bf41da8e/hadoop-hdfs-project/hadoop-hdfs-client/src/main/java/org/apache/hadoop/hdfs/web/WebHdfsFileSystem.java#L1954-L1990","documentation":"Defensive default branch inside the JSON decoder used by WebHdfsFileSystem.getFileBlockLocations: the operation passed to the private helper must be GETFILEBLOCKLOCATIONS or GET_BLOCK_LOCATIONS, and any other GetOpParam.Op throws this IOException when decoding the response. The public API only ever passes those two ops (chosen by isServerHCFSCompatible, with automatic fallback at WebHdfsFileSystem.java:1934-1951), so reaching this branch means an internal caller, fork, or test passed an unhandled operation.","triggerScenarios":"Invoking the private getFileBlockLocations(operation, p, offset, length) with a GetOpParam.Op other than GETFILEBLOCKLOCATIONS/GET_BLOCK_LOCATIONS; typically a patched client that added a new op to GetOpParam.Op without extending this switch, or reflection-based tests calling the private method.","commonSituations":"Custom Hadoop forks that add block-location REST ops; unit tests driving internal runner classes; version-skewed jars where a new op enum value reaches an older WebHdfsFileSystem decode switch. Not reachable through the public FileSystem API.","solutions":["Use the public FileSystem#getFileBlockLocations(FileStatus/Path, offset, len) API, which selects the correct op and falls back automatically","If you maintain a fork adding an op, add a matching case to the switch in decodeResponse before the default branch","Check for mixed hadoop-hdfs-client versions on the classpath (mvn dependency:tree | grep hdfs-client) so the enum and the decoder come from the same jar"],"exampleFix":"// before: new op reaches decoder without a case -> default: throw\n// after: handle it explicitly\nswitch (operation) {\ncase GETFILEBLOCKLOCATIONS:\n  return JsonUtilClient.toBlockLocationArray(json);\ncase GET_BLOCK_LOCATIONS:\n  return DFSUtilClient.locatedBlocks2Locations(JsonUtilClient.toLocatedBlocks(json));\ncase MY_NEW_OP:\n  return decodeMyNewOp(json);\ndefault:\n  throw new IOException(\"Unknown operation \" + operation.name());\n}","handlingStrategy":"validation","validationCode":"private static final Set<GetOpParam.Op> BLOCK_LOCATIONS_OPS =\n    EnumSet.of(GetOpParam.Op.GETFILEBLOCKLOCATIONS,\n              GetOpParam.Op.GET_BLOCK_LOCATIONS);\n\nif (!BLOCK_LOCATIONS_OPS.contains(operation)) {\n  throw new IllegalArgumentException(\n      \"Unsupported block-locations op: \" + operation);\n}","typeGuard":"static boolean isBlockLocationsOp(GetOpParam.Op op) {\n  return op == GetOpParam.Op.GETFILEBLOCKLOCATIONS\n      || op == GetOpParam.Op.GET_BLOCK_LOCATIONS;\n}","tryCatchPattern":null,"preventionTips":["Do not call the private getFileBlockLocations(op,...) runner; use the public FileSystem API","When forking/adding GetOpParam.Op values, grep for every switch over the enum and extend them","Pin a single hadoop-hdfs-client version across the classpath"],"tags":["webhdfs","internal-api","defensive-check","block-locations"],"backgroundTag":"unhandled-enum-case","analyzedSha":"2add9630210752f88ceb1bb74eb65e37bf41da8e","analyzedAt":"2026-08-22T19:55:07.957Z","schemaVersion":2},"datasetVersion":"2026-08-22T20:17:22.307Z"}