diff --git a/soda-core/src/soda_core/common/soda_cloud.py b/soda-core/src/soda_core/common/soda_cloud.py index 6c2cade4b..bba752701 100644 --- a/soda-core/src/soda_core/common/soda_cloud.py +++ b/soda-core/src/soda_core/common/soda_cloud.py @@ -643,7 +643,8 @@ def verify_contract_on_runner( file_id: Optional[str] = self._upload_contract_yaml_file(contract_yaml_str_original) if not file_id: logger.critical("Contract wasn't uploaded so skipping sending the results to Soda Cloud") - return [] + verification_result.sending_results_to_soda_cloud_failed = True + return verification_result verify_contract_command: dict = { "type": "sodaCoreVerifyContract" if publish_results else "sodaCoreTestContract", diff --git a/soda-tests/tests/unit/test_soda_cloud.py b/soda-tests/tests/unit/test_soda_cloud.py index 06121a31c..877c65e9c 100644 --- a/soda-tests/tests/unit/test_soda_cloud.py +++ b/soda-tests/tests/unit/test_soda_cloud.py @@ -798,3 +798,37 @@ def test_build_token_usage_dicts_empty_when_no_usage(): mock_result.token_usage = [] assert _build_token_usage_dicts(mock_result) == [] + + +def test_verify_contract_on_runner_returns_result_when_upload_fails(): + """If uploading the contract file fails (no fileId), the method must return a ContractVerificationResult + and set sending_results_to_soda_cloud_failed=True rather than returning a list or other type.""" + from soda_core.common.yaml import ContractYamlSource + from soda_core.contracts.impl.contract_yaml import ContractYaml + + # First response: permission check allowed + # Second response: upload contract returns 200 but without fileId → treated as upload failure + responses = [ + MockResponse(status_code=200, json_object={"allowed": True}), + MockResponse(method=MockHttpMethod.POST, status_code=200, json_object={}), + ] + mock_cloud = MockSodaCloud(responses) + + result = mock_cloud.verify_contract_on_runner( + ContractYaml.parse( + ContractYamlSource.from_str( + """ + dataset: test/some/schema/CUSTOMERS + columns: + - name: id + """ + ) + ), + variables={}, + blocking_timeout_in_minutes=60, + publish_results=False, + verbose=False, + ) + + assert isinstance(result, ContractVerificationResult) + assert result.sending_results_to_soda_cloud_failed is True