From cba621c2f81f5ceaf2fe1e2d2f11ced5ceeca4b7 Mon Sep 17 00:00:00 2001 From: Morris Jencen Chavez Date: Fri, 25 Sep 2026 19:16:11 +0000 Subject: [PATCH] fix: flatten validation error arrays on endpoint creation The Create Endpoint modal submits via a raw axios call so it can read back the one-time plain_secret on success, bypassing Inertia's normal form submission which flattens Laravel's per-field array of validation messages into a single string. Because form.setError() received the raw array and InputError.vue renders its message as a string, every validation failure (duplicate name, invalid URL, etc.) showed the user a raw JSON blob like ["The name field is required."] instead of a readable message. Flatten each field's error array to its first message before calling form.setError(), matching the shape Inertia's own form submissions already produce elsewhere in the app. --- resources/js/Pages/Endpoints/Index.vue | 14 +++++++- ...ndpointCreateValidationErrorFormatTest.php | 35 +++++++++++++++++++ 2 files changed, 48 insertions(+), 1 deletion(-) create mode 100644 tests/Feature/EndpointCreateValidationErrorFormatTest.php diff --git a/resources/js/Pages/Endpoints/Index.vue b/resources/js/Pages/Endpoints/Index.vue index 93e0f75..e4ecdb8 100644 --- a/resources/js/Pages/Endpoints/Index.vue +++ b/resources/js/Pages/Endpoints/Index.vue @@ -415,7 +415,19 @@ async function saveEndpoint() { showOneTimeSecret(response.data.plain_secret) } catch (error) { if (error.response?.data?.errors) { - form.setError(error.response.data.errors) + // Laravel's JSON validation-error response shapes each field + // as an array of messages. A normal Inertia form submission + // flattens these before they reach the client, but this is a + // raw axios call, so it must be flattened here too — otherwise + // form.setError() stores the array itself and InputError.vue + // (which expects a string) renders it as a JSON blob. + const errors = Object.fromEntries( + Object.entries(error.response.data.errors).map(([field, messages]) => [ + field, + Array.isArray(messages) ? messages[0] : messages, + ]) + ) + form.setError(errors) } else { alert('Failed to save endpoint. Please try again.') } diff --git a/tests/Feature/EndpointCreateValidationErrorFormatTest.php b/tests/Feature/EndpointCreateValidationErrorFormatTest.php new file mode 100644 index 0000000..03bc097 --- /dev/null +++ b/tests/Feature/EndpointCreateValidationErrorFormatTest.php @@ -0,0 +1,35 @@ +withPersonalTeam()->create(); + + $response = $this->actingAs($user)->postJson('/endpoints', [ + 'name' => '', + 'url' => 'not-a-url', + ]); + + $response->assertStatus(422); + $response->assertJsonValidationErrors(['name', 'url']); + $this->assertIsArray($response->json('errors.name')); + $this->assertIsArray($response->json('errors.url')); + } +}