{"record":{"id":"c9b5ff089d78c450","repo":"OpenFeign/feign","slug":"soap-only-supports-decoding-raw-types-found-s","errorCode":null,"errorMessage":"SOAP only supports decoding raw types. Found %s","messagePattern":"SOAP only supports decoding raw types\\. Found (.+?)","errorType":"exception","errorClass":"UnsupportedOperationException","httpStatus":null,"severity":"error","filePath":"soap-jakarta/src/main/java/feign/soap/SOAPDecoder.java","lineNumber":106,"sourceCode":"    this.useFirstChild = false;\n  }\n\n  private SOAPDecoder(Builder builder) {\n    this.soapProtocol = builder.soapProtocol;\n    this.jaxbContextFactory = builder.jaxbContextFactory;\n    this.useFirstChild = builder.useFirstChild;\n  }\n\n  @Override\n  public Object decode(Response response, Type type) throws IOException {\n    if (response.status() == 404) return Util.emptyValueOf(type);\n    if (response.body() == null) return null;\n    while (type instanceof ParameterizedType) {\n      ParameterizedType ptype = (ParameterizedType) type;\n      type = ptype.getRawType();\n    }\n    if (!(type instanceof Class)) {\n      throw new UnsupportedOperationException(\n          \"SOAP only supports decoding raw types. Found \" + type);\n    }\n\n    try {\n      SOAPMessage message =\n          MessageFactory.newInstance(soapProtocol)\n              .createMessage(null, response.body().asInputStream());\n      if (message.getSOAPBody() != null) {\n        if (message.getSOAPBody().hasFault()) {\n          throw new SOAPFaultException(message.getSOAPBody().getFault());\n        }\n\n        Unmarshaller unmarshaller = jaxbContextFactory.createUnmarshaller((Class<?>) type);\n\n        if (this.useFirstChild) {\n          return unmarshaller.unmarshal(message.getSOAPBody().getFirstChild());\n        } else {\n          return unmarshaller.unmarshal(message.getSOAPBody().extractContentAsDocument());","sourceCodeStart":88,"sourceCodeEnd":124,"githubUrl":"https://github.com/OpenFeign/feign/blob/e2a1e27560a1e68840c34f031afca88b36096e30/soap-jakarta/src/main/java/feign/soap/SOAPDecoder.java#L88-L124","documentation":"The jakarta SOAP decoder can only unmarshal the response body into a raw class, because JAXB/SAJ unmarshalling requires a Class. Before decoding, it strips ParameterizedType wrappers (e.g. List<Foo>) to the raw type; if the type is still not a Class (e.g. a generic type variable or wildcard), it throws UnsupportedOperationException. Note generics like List<Foo> are partially handled by taking the raw type, but non-class types are rejected.","triggerScenarios":"Declaring a Feign interface method whose return type is not resolvable to a raw Class after unwrapping ParameterizedTypes — e.g. a generic type variable T, wildcard, or generic array — and calling that method so decode() runs on the response.","commonSituations":"Using a generic client interface with a type variable return type; declaring ResponseEntity-ish wrappers that are not simple parameterized types; copy-pasting a decoder config from the non-generic SOAP module.","solutions":["Change the Feign method return type to a concrete raw class (or List<ConcreteClass>, which unwraps to List's raw type) instead of a generic type variable or wildcard.","If you need generics, build a dedicated interface per concrete type or supply a custom Decoder that resolves the type variable before delegating to SOAPDecoder."],"exampleFix":"// before\n<T> T getOrder();\n// after\nOrder getOrder();","handlingStrategy":"type-guard","validationCode":"static boolean isSoapDecodable(Type type) {\n  while (type instanceof ParameterizedType) {\n    type = ((ParameterizedType) type).getRawType();\n  }\n  return type instanceof Class;\n}","typeGuard":"if (!isSoapDecodable(methodReturnType)) {\n  throw new IllegalArgumentException(\"SOAP method return type must resolve to a raw Class\");\n}","tryCatchPattern":"try {\n  return soapClient.call();\n} catch (UnsupportedOperationException e) {\n  if (e.getMessage() != null && e.getMessage().contains(\"SOAP only supports decoding raw types\")) {\n    // fix return type to a concrete class\n  }\n  throw e;\n}","preventionTips":["Never declare type-variable or wildcard return types on SOAP Feign methods.","Keep a non-generic interface per concrete SOAP response type.","Add an archunit/reflection test that asserts all SOAP client method types resolve to Class."],"tags":["soap","jaxb","generics","decoder","unsupported-operation"],"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"}