Repository: tefra/xsdata

Issue:
SOAP Body sometimes generated with mandatory `fault` field
**Context**

I am currently investigating if I can use xsdata for consuming a SOAP service that I have to integrate with. So far, I see a lot of good stuff. I'm using xsdata-pydantic, and am very happy with the generated Pydantic schema classes. I was quickly able to build a request to send using these.

**Issue**

Parsing the response using the built-in Client fails. When using `client.send(...)`, validation fails on the output message that is returned from the service:

```
1 validation error for Body
fault
  Field required [type=missing, input_value={'can_response': CanRespo...cel.'), request_uid='')}, input_type=dict]
    For further information visit https://errors.pydantic.dev/2.9/v/missing
```

It tells me that the `fault` field is required, but the service does not return a fault element.

**My current work-around**

I found out that the broken behavior is related to `kw_only = True` (see my updated in this thread). I was able to get SOAP calls working by:

- not using `pydantic` but `dataclasses` as the format (because `pydantic` enforced `kw_only = True`;
- not using `xsdata --kw-only` for generating the schema classes.


Discussion:
sonarcloud[bot]: ## [![Quality Gate Passed](https://sonarsource.github.io/sonarcloud-github-static-resources/v2/checks/QualityGateBadge/qg-passed-20px.png 'Quality Gate Passed')](https://sonarcloud.io/dashboard?id=tefra_xsdata&pullRequest=1099) **Quality Gate passed**  
Issues  
![](https://sonarsource.github.io/sonarcloud-github-static-resources/v2/common/passed-16px.png '') [0 New issues](https://sonarcloud.io/project/issues?id=tefra_xsdata&pullRequest=1099&issueStatuses=OPEN,CONFIRMED&sinceLeakPeriod=true)  
![](https://sonarsource.github.io/sonarcloud-github-static-resources/v2/common/accepted-16px.png '') [0 Accepted issues](https://sonarcloud.io/project/issues?id=tefra_xsdata&pullRequest=1099&issueStatuses=ACCEPTED)

Measures  
![](https://sonarsource.github.io/sonarcloud-github-static-resources/v2/common/passed-16px.png '') [0 Security Hotspots](https://sonarcloud.io/project/security_hotspots?id=tefra_xsdata&pullRequest=1099&issueStatuses=OPEN,CONFIRMED&sinceLeakPeriod=true)  
![](https://sonarsource.github.io/sonarcloud-github-static-resources/v2/common/passed-16px.png '') [0.0% Coverage on New Code](https://sonarcloud.io/component_measures?id=tefra_xsdata&pullRequest=1099&metric=new_coverage&view=list)  
![](https://sonarsource.github.io/sonarcloud-github-static-resources/v2/common/passed-16px.png '') [0.0% Duplication on New Code](https://sonarcloud.io/component_measures?id=tefra_xsdata&pullRequest=1099&metric=new_duplicated_lines_density&view=list)  
  
[See analysis details on SonarQube Cloud](https://sonarcloud.io/dashboard?id=tefra_xsdata&pullRequest=1099)


codecov[bot]: ## [Codecov](https://app.codecov.io/gh/tefra/xsdata/pull/1099?dropdown=coverage&src=pr&el=h1&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=Chris+Tsou) Report
All modified and coverable lines are covered by tests :white_check_mark:
> Project coverage is 99.75%. Comparing base [(`95755fe`)](https://app.codecov.io/gh/tefra/xsdata/commit/95755fe11e253b38ee1df5112880a0529203a15f?dropdown=coverage&el=desc&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=Chris+Tsou) to head [(`31c22a5`)](https://app.codecov.io/gh/tefra/xsdata/commit/31c22a51c3b15459c4aec592b8ff54ac0aaa9b32?dropdown=coverage&el=desc&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=Chris+Tsou).

<details><summary>Additional details and impacted files</summary>


```diff
@@             Coverage Diff             @@
##              main    #1099      +/-   ##
===========================================
- Coverage   100.00%   99.75%   -0.25%     
===========================================
  Files          115      115              
  Lines         9281     9283       +2     
  Branches      1418     1419       +1     
===========================================
- Hits          9281     9260      -21     
- Misses           0       19      +19     
- Partials         0        4       +4     
```

</details>

[:umbrella: View full report in Codecov by Sentry](https://app.codecov.io/gh/tefra/xsdata/pull/1099?dropdown=coverage&src=pr&el=continue&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=Chris+Tsou).   
:loudspeaker: Have feedback on the report? [Share it here](https://about.codecov.io/codecov-pr-comment-feedback/?utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=Chris+Tsou).


Patch:
diff --git a/xsdata/codegen/mappers/definitions.py b/xsdata/codegen/mappers/definitions.py
index 1a5f8a88..c3402c38 100644
--- a/xsdata/codegen/mappers/definitions.py
+++ b/xsdata/codegen/mappers/definitions.py
@@ -259,6 +259,9 @@ class DefinitionsMapper:
             ),
         )
 
+        for attr in body.attrs:
+            attr.restrictions.min_occurs = 0
+
     @classmethod
     def build_envelope_class(
         cls,


Test patch:
diff --git a/tests/codegen/mappers/test_definitions.py b/tests/codegen/mappers/test_definitions.py
index 123059be..12de60b5 100644
--- a/tests/codegen/mappers/test_definitions.py
+++ b/tests/codegen/mappers/test_definitions.py
@@ -504,6 +504,9 @@ class DefinitionsMapperTests(FactoryTestCase):
         self.assertEqual(expected_fault_attr, body.attrs[0])
         self.assertEqual(expected_fault_attrs, body.inner[0].attrs)
 
+        for attr in body.attrs:
+            self.assertTrue(attr.is_optional)
+
     def test_build_envelope_fault_with_detail_messages(self):
         body = ClassFactory.create(qname="Body")
         target = ClassFactory.create()