From f9af8e20688f908959ce04231029f44a79f6787c Mon Sep 17 00:00:00 2001 From: Arthur Date: Mon, 30 Mar 2026 15:36:51 -0700 Subject: [PATCH] Require data_file when data_source is specified MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit data_source alone is not a valid creation payload — a data_file must also be provided to identify which file within the source to sync. Add the corresponding validation error and a test to cover the case. Co-Authored-By: Claude Sonnet 4.6 --- netbox/extras/api/serializers_/scripts.py | 8 ++++++-- netbox/extras/tests/test_api.py | 11 +++++++++++ 2 files changed, 17 insertions(+), 2 deletions(-) diff --git a/netbox/extras/api/serializers_/scripts.py b/netbox/extras/api/serializers_/scripts.py index 94fa98fd8..f054a6a37 100644 --- a/netbox/extras/api/serializers_/scripts.py +++ b/netbox/extras/api/serializers_/scripts.py @@ -57,9 +57,13 @@ class ScriptModuleSerializer(ValidatedModelSerializer): raise serializers.ValidationError( _("Cannot upload a file and sync from a data source.") ) - if self.instance is None and not upload_file and not has_data_file and not has_data_source: + if has_data_source and not has_data_file: raise serializers.ValidationError( - _("Must upload a file or provide a data source or data file to sync.") + _("A data file must be specified when syncing from a data source.") + ) + if self.instance is None and not upload_file and not has_data_file: + raise serializers.ValidationError( + _("Must upload a file or provide a data source and data file to sync.") ) return data diff --git a/netbox/extras/tests/test_api.py b/netbox/extras/tests/test_api.py index 86e2bfb65..650ecfcf6 100644 --- a/netbox/extras/tests/test_api.py +++ b/netbox/extras/tests/test_api.py @@ -1441,6 +1441,17 @@ class ScriptUploadTest(APITestCase): ) self.assertHttpStatus(response, status.HTTP_400_BAD_REQUEST) + def test_data_source_without_data_file_fails(self): + """data_source alone (without data_file) must be rejected.""" + self.add_permissions('extras.add_scriptmodule', 'core.add_managedfile') + response = self.client.post( + self.url_list, + {'data_source': 1}, + format='multipart', + **self.header, + ) + self.assertHttpStatus(response, status.HTTP_400_BAD_REQUEST) + def test_upload_script_module_without_file_fails(self): self.add_permissions('extras.add_scriptmodule', 'core.add_managedfile') response = self.client.post(self.url_list, {}, format='json', **self.header)