Repository: hikari-py/hikari
Pull request #2330 (2025-04-27 11:54:44)

Fix sending modal builders
We didn't account for the new changes well when sending modals. A nicer fix for this will come in the future which will work typing wise too, to prevent this in the future


Patch:
diff --git a/changes/2330.bugfix.md b/changes/2330.bugfix.md
new file mode 100644
index 00000000..a06dc5b5
--- /dev/null
+++ b/changes/2330.bugfix.md
@@ -0,0 +1,1 @@
+Fix modal creations through builders
diff --git a/hikari/impl/rest.py b/hikari/impl/rest.py
index 0866458f..7da98093 100644
--- a/hikari/impl/rest.py
+++ b/hikari/impl/rest.py
@@ -4403,20 +4403,20 @@ async def create_modal_response(
             msg = "Must specify exactly only one of 'component' or 'components'"
             raise ValueError(msg)
 
-        route = routes.POST_INTERACTION_RESPONSE.compile(interaction=interaction, token=token)
+        if component:
+            components = (component,)
 
-        body = data_binding.JSONObjectBuilder()
-        body.put("type", base_interactions.ResponseType.MODAL)
+        route = routes.POST_INTERACTION_RESPONSE.compile(interaction=interaction, token=token)
 
         data = data_binding.JSONObjectBuilder()
         data.put("title", title)
         data.put("custom_id", custom_id)
+        # Component builders return a tuple of (payload, files), but we only care about
+        # the payload, as there is no way to upload anything to a modal
+        data.put_array("components", components, conversion=lambda c: c.build()[0])
 
-        if component:
-            components = (component,)
-
-        data.put_array("components", components, conversion=lambda c: c.build())
-
+        body = data_binding.JSONObjectBuilder()
+        body.put("type", base_interactions.ResponseType.MODAL)
         body.put("data", data)
 
         await self._request(route, json=body, auth=None)


Test patch:
diff --git a/tests/hikari/impl/test_rest.py b/tests/hikari/impl/test_rest.py
index 9f0de105..c8b1b007 100644
--- a/tests/hikari/impl/test_rest.py
+++ b/tests/hikari/impl/test_rest.py
@@ -6350,7 +6350,9 @@ async def test_create_autocomplete_response_for_deprecated_command_choices(self,
     async def test_create_modal_response(self, rest_client):
         expected_route = routes.POST_INTERACTION_RESPONSE.compile(interaction=1235431, token="snek")
         rest_client._request = mock.AsyncMock()
-        component = mock.Mock()
+        mock_payload = mock.Mock()
+        mock_files = mock.Mock()
+        component = mock.Mock(build=mock.Mock(return_value=(mock_payload, mock_files)))
 
         await rest_client.create_modal_response(
             StubModel(1235431), "snek", title="title", custom_id="idd", component=component
@@ -6358,17 +6360,16 @@ async def test_create_modal_response(self, rest_client):
 
         rest_client._request.assert_awaited_once_with(
             expected_route,
-            json={
-                "type": 9,
-                "data": {"title": "title", "custom_id": "idd", "components": [component.build.return_value]},
-            },
+            json={"type": 9, "data": {"title": "title", "custom_id": "idd", "components": [mock_payload]}},
             auth=None,
         )
 
     async def test_create_modal_response_with_plural_args(self, rest_client):
         expected_route = routes.POST_INTERACTION_RESPONSE.compile(interaction=1235431, token="snek")
         rest_client._request = mock.AsyncMock()
-        component = mock.Mock()
+        mock_payload = mock.Mock()
+        mock_files = mock.Mock()
+        component = mock.Mock(build=mock.Mock(return_value=(mock_payload, mock_files)))
 
         await rest_client.create_modal_response(
             StubModel(1235431), "snek", title="title", custom_id="idd", components=[component]
@@ -6376,10 +6377,7 @@ async def test_create_modal_response_with_plural_args(self, rest_client):
 
         rest_client._request.assert_awaited_once_with(
             expected_route,
-            json={
-                "type": 9,
-                "data": {"title": "title", "custom_id": "idd", "components": [component.build.return_value]},
-            },
+            json={"type": 9, "data": {"title": "title", "custom_id": "idd", "components": [mock_payload]}},
             auth=None,
         )