diff --git a/frontend/testing/unit/components/ApiKeySetupModal.test.tsx b/frontend/testing/unit/components/ApiKeySetupModal.test.tsx
new file mode 100644
index 000000000..5d511b91e
--- /dev/null
+++ b/frontend/testing/unit/components/ApiKeySetupModal.test.tsx
@@ -0,0 +1,67 @@
+import React from 'react'
+import { render, screen } from '@testing-library/react'
+import userEvent from '@testing-library/user-event'
+import { describe, it, expect, beforeEach, vi } from 'vitest'
+import ApiKeySetupModal from '../../../src/components/ApiKeySetupModal'
+
+vi.mock('../../../src/api', () => ({
+ authenticateWithApiKey: vi.fn(),
+}))
+
+import { authenticateWithApiKey } from '../../../src/api'
+
+describe('ApiKeySetupModal Error Handling', () => {
+ const defaultProps = {
+ onSaved: vi.fn(),
+ }
+
+ beforeEach(() => {
+ vi.clearAllMocks()
+ })
+
+ it('shows standard validation error on empty submission', async () => {
+ const user = userEvent.setup()
+ render()
+
+ await user.click(screen.getByRole('button', { name: /save and connect/i }))
+
+ const alert = await screen.findByRole('alert')
+ expect(alert).toHaveTextContent('Please enter the API key.')
+ expect(authenticateWithApiKey).not.toHaveBeenCalled()
+ })
+
+ it('shows backend error message when api key is rejected', async () => {
+ const user = userEvent.setup()
+ const backendErrorMsg = 'Invalid/Expired API token'
+ vi.mocked(authenticateWithApiKey).mockRejectedValue(new Error(backendErrorMsg))
+
+ render()
+
+ const input = screen.getByLabelText('Backend API Key')
+ await user.type(input, 'bad-key')
+ await user.click(screen.getByRole('button', { name: /save and connect/i }))
+
+ const alert = await screen.findByRole('alert')
+ expect(alert).toHaveTextContent(backendErrorMsg)
+ expect(defaultProps.onSaved).not.toHaveBeenCalled()
+ })
+
+ it('ensures sensitive key text is not echoed in failure UI', async () => {
+ const user = userEvent.setup()
+ const sensitiveKey = 'SUPER_SECRET_TOKEN_999'
+ vi.mocked(authenticateWithApiKey).mockRejectedValue(new Error('Authentication failed. Check the API key.'))
+
+ render()
+
+ const input = screen.getByLabelText('Backend API Key')
+ await user.type(input, sensitiveKey)
+ await user.click(screen.getByRole('button', { name: /save and connect/i }))
+
+ // Assert useful error message is visible
+ const alert = await screen.findByRole('alert')
+ expect(alert).toBeInTheDocument()
+
+ // Assert sensitive key text is NOT in the error message / failure UI text content
+ expect(alert.textContent).not.toContain(sensitiveKey)
+ })
+})