{"record":{"id":"f76060a6dfe64c7c","repo":"OpenFeign/feign","slug":"s-is-not-a-type-supported-by-this-decoder","errorCode":null,"errorMessage":"%s is not a type supported by this decoder.","messagePattern":"(.+?) is not a type supported by this decoder\\.","errorType":"exception","errorClass":"DecodeException","httpStatus":null,"severity":"error","filePath":"json/src/main/java/feign/json/JsonDecoder.java","lineNumber":67,"sourceCode":" *                      .decoder(new JsonDecoder())\n *                      .target(GitHub.class, \"https://api.github.com\");\n *\n *   JSONArray contributors = github.contributors(\"openfeign\", \"feign\");\n *\n *   System.out.println(contributors.getJSONObject(0).getString(\"login\"));\n * </pre>\n */\npublic class JsonDecoder implements Decoder, PredicatedDecoder, feign.codec.JsonDecoder {\n\n  @Override\n  public Object decode(Response response, Type type) throws IOException, DecodeException {\n    if (response.status() == 404 || response.status() == 204)\n      if (Map.class.equals(type)) return null;\n      else if (JSONObject.class.isAssignableFrom((Class<?>) type)) return new JSONObject();\n      else if (JSONArray.class.isAssignableFrom((Class<?>) type)) return new JSONArray();\n      else if (String.class.equals(type)) return null;\n      else\n        throw new DecodeException(\n            response.status(),\n            format(\"%s is not a type supported by this decoder.\", type),\n            response.request());\n    if (response.body() == null) return null;\n    try (Reader reader = response.body().asReader(response.charset())) {\n      Reader bodyReader = (reader.markSupported()) ? reader : new BufferedReader(reader);\n      bodyReader.mark(1);\n      if (bodyReader.read() == -1) {\n        return null; // Empty body\n      }\n      bodyReader.reset();\n      return decodeBody(response, type, bodyReader);\n    } catch (JSONException jsonException) {\n      if (jsonException.getCause() != null && jsonException.getCause() instanceof IOException) {\n        throw (IOException) jsonException.getCause();\n      }\n      throw new DecodeException(\n          response.status(), jsonException.getMessage(), response.request(), jsonException);","sourceCodeStart":49,"sourceCodeEnd":85,"githubUrl":"https://github.com/OpenFeign/feign/blob/e2a1e27560a1e68840c34f031afca88b36096e30/json/src/main/java/feign/json/JsonDecoder.java#L49-L85","documentation":"JsonDecoder.decode (feign-json, built on org.json) supports only Map, JSONObject, JSONArray and String return types. When a 404/204 response is decoded to any other type, it throws DecodeException saying the type is not supported; the decoder parses JSON into org.json structures and cannot bind arbitrary POJOs.","triggerScenarios":"Declaring a Feign method returning a custom POJO (e.g. MyDto) with JsonDecoder, and the server responds 404 or 204; the empty-body branch cannot map the declared type and throws.","commonSituations":"Using feign-json expecting POJO binding like Jackson/Gson; typed DTO returns on no-content or not-found endpoints; migrating from another decoder module.","solutions":["Change the method return type to Map, JSONObject, JSONArray, or String.","For 404/204 endpoints, return a supported type (Map or String yields null; JSONObject/JSONArray yield empty objects).","Switch to the Jackson or Gson module for POJO decoding.","Catch DecodeException around calls to not-found-prone endpoints."],"exampleFix":"// before\nUserDto getUser(); // 404 -> DecodeException\n// after\norg.json.JSONObject getUser(); // returns new JSONObject() on 404/204","handlingStrategy":"type-guard","validationCode":"// before declaring a feign-json method\ntypeCheck(returnType);","typeGuard":"boolean isJsonDecoderType(java.lang.reflect.Type t) {\n  if (!(t instanceof Class)) return false;\n  Class<?> c = (Class<?>) t;\n  return Map.class.equals(c) || JSONObject.class.isAssignableFrom(c)\n      || JSONArray.class.isAssignableFrom(c) || String.class.equals(c);\n}","tryCatchPattern":"try {\n  result = api.get();\n} catch (DecodeException e) {\n  if (e.status() == 404 || e.status() == 204) {\n    // unsupported return type on empty/not-found response; adjust type or handle\n  } else { throw e; }\n}","preventionTips":["Restrict feign-json methods to Map/JSONObject/JSONArray/String returns.","Use the Jackson or Gson module for POJO mapping.","Handle 404/204 endpoints with supported return types."],"tags":["json","decode","unsupported-type"],"backgroundTag":"unsupported-operation","analyzedSha":"e2a1e27560a1e68840c34f031afca88b36096e30","analyzedAt":"2026-09-10T12:37:37.238Z","contentChangedAt":"2026-09-10T12:37:37.238Z","schemaVersion":2},"datasetVersion":"2026-09-16T09:17:16.951Z"}