Skip to content

SOAP transport: wrong XML namespaces, lost <soap:header> routing, and broken array serialization #9464

@zcag

Description

@zcag

Issue workflow progress

  • 1. The issue provides a reproduction (minimal synthetic WSDL — see Reproduction below)
  • 2. A failing test has been provided
  • 3. A local solution has been provided
  • 4. A pull request is pending review

Describe the bug

The SOAP transport produces malformed envelopes for any WSDL that:

  1. Defines its types across multiple <xsd:schema> blocks with different targetNamespace values, or
  2. Uses a <soap:header> binding to route part of the input message into <soap:Header>, or
  3. Has any array-valued (maxOccurs="unbounded") input element.

These three problems often appear together — they're all triggered by a typical TMForum-style WSDL — but each is independent.

Concretely:

  1. Wrong namespace on every element. Every body element is qualified with the WSDL bindingNamespace, regardless of which XSD schema the type is actually declared in. A WSDL with four schemas in four namespaces will still produce a single `xmlns:body=...` and prefix everything with it.

  2. <soap:header> bindings are ignored. Message parts that the WSDL routes to `soap:Header` end up inside `soap:Body` next to the request payload. The auth header for many enterprise SOAP services lives here.

  3. Arrays serialize as <prefix:0>, <prefix:1>, … because both `normalizeArgsForConverter` and `prefixWithAlias` use `for..in` on arrays, which iterates over numeric keys.

To Reproduce

Minimal synthetic WSDL (also added as a fixture in the proposed fix's PR):

<wsdl:definitions ... targetNamespace=\"http://example.com/order-service\">
  <wsdl:types>
    <xsd:schema targetNamespace=\"http://example.com/auth\">
      <xsd:element name=\"AuthHeader\">...</xsd:element>
    </xsd:schema>
    <xsd:schema targetNamespace=\"http://example.com/orders\">
      <xsd:element name=\"SubmitOrder\">
        <xsd:complexType>
          <xsd:sequence>
            <xsd:element name=\"items\" type=\"tns:OrderItem\" maxOccurs=\"unbounded\"/>
            ...
          </xsd:sequence>
        </xsd:complexType>
      </xsd:element>
    </xsd:schema>
  </wsdl:types>
  <wsdl:message name=\"SubmitOrderRequest\">
    <wsdl:part name=\"auth\" element=\"auth:AuthHeader\"/>
    <wsdl:part name=\"body\" element=\"ord:SubmitOrder\"/>
  </wsdl:message>
  <wsdl:binding ...>
    <wsdl:operation name=\"submitOrder\">
      <wsdl:input>
        <soap:header message=\"tns:SubmitOrderRequest\" part=\"auth\" use=\"literal\"/>
        <soap:body use=\"literal\"/>
      </wsdl:input>
      ...

A query that supplies `AuthHeader`, `SubmitOrder` and an array of `items` produces (current code, no `bodyAlias`):

<soap:Envelope xmlns:body=\"http://example.com/order-service\">
  <soap:Body>
    <body:AuthHeader>...</body:AuthHeader>            <!-- BUG 2: header in body -->
    <body:SubmitOrder>                                 <!-- BUG 1: wrong ns (orders, not bindingNs) -->
      <body:items>
        <body:0>                                       <!-- BUG 3: array index as element -->
          <body:productId>p1</body:productId>...
        </body:0>
        <body:1>...</body:1>
      </body:items>
    </body:SubmitOrder>
  </soap:Body>
</soap:Envelope>

Expected (and what the fix produces):

<soap:Envelope xmlns:auth=\"http://example.com/auth\" xmlns:orders=\"http://example.com/orders\">
  <soap:Header>
    <auth:AuthHeader><auth:token>...</auth:token></auth:AuthHeader>
  </soap:Header>
  <soap:Body>
    <orders:SubmitOrder>
      <orders:items><orders:productId>p1</orders:productId>...</orders:items>
      <orders:items><orders:productId>p2</orders:productId>...</orders:items>
    </orders:SubmitOrder>
  </soap:Body>
</soap:Envelope>

Expected behavior

  • Each element is qualified with the namespace of the schema where its type is declared.
  • Message parts the WSDL routes to `soap:header` go into `soap:Header`.
  • Array-valued args produce repeated sibling elements, not numeric child indices.
  • WSDLs with a single XSD namespace and no `bodyAlias` continue to produce the same envelope as today (no regression).

Environment

  • OS: Linux
  • `@graphql-mesh/transport-soap`: latest (master)
  • `@omnigraph/soap`: latest (master)
  • NodeJS: 20+

Additional context

I have a fix ready with two new tests (a synthetic multi-namespace fixture covering all three bugs at once, and a regression guard against `tempconvert.wsdl` proving single-namespace + no-`bodyAlias` is byte-identical to today's output). End-to-end verified against a production TMForum MTOP service. Will open a PR referencing this issue.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions