{"record":{"id":"84d5dcc480f01c6b","repo":"OpenFeign/feign","slug":"soap-only-supports-decoding-raw-types-found-s-84d5dc","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/src/main/java/feign/soap/SOAPDecoder.java","lineNumber":110,"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":92,"sourceCodeEnd":128,"githubUrl":"https://github.com/OpenFeign/feign/blob/e2a1e27560a1e68840c34f031afca88b36096e30/soap/src/main/java/feign/soap/SOAPDecoder.java#L92-L128","documentation":"Same check as its jakarta sibling in the javax-based soap module: SOAPDecoder.decode() unwraps ParameterizedTypes to raw types and requires the result to be a Class, since JAXB unmarshalling needs a Class. Otherwise it throws UnsupportedOperationException naming the offending type.","triggerScenarios":"A Feign method in a javax-soap client returns a type that is not resolvable to a raw Class (type variable, wildcard, or other non-Class Type) and the method is invoked, triggering decode() on the SOAP response.","commonSituations":"Generic interface methods with type-variable return types; frameworks passing unresolved generic signatures; migrating code that used raw Object returns.","solutions":["Declare the method return type as a concrete class (List<MyType> is fine since the raw type is used).","Create one non-generic interface per concrete SOAP response type.","Wrap SOAPDecoder with a custom Decoder that substitutes type variables with concrete classes first."],"exampleFix":"// before\npublic interface Api<T> { T find(); }\n// after\npublic interface OrderApi { Order find(); }","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(returnType)) {\n  throw new IllegalArgumentException(\"SOAP return type must resolve to a raw Class\");\n}","tryCatchPattern":"try {\n  return client.find();\n} catch (UnsupportedOperationException e) {\n  if (e.getMessage() != null && e.getMessage().contains(\"SOAP only supports decoding raw types\")) {\n    // replace generic return type with a concrete class\n  }\n  throw e;\n}","preventionTips":["Use concrete classes for SOAP method return types.","Avoid type-variable returns in javax-soap Feign interfaces.","Add a reflection-based test asserting decodable types."],"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"}