diff --git a/frontend/src/components/workspace/settings/memory-settings-page.tsx b/frontend/src/components/workspace/settings/memory-settings-page.tsx
index 3a67eadee..982090f8b 100644
--- a/frontend/src/components/workspace/settings/memory-settings-page.tsx
+++ b/frontend/src/components/workspace/settings/memory-settings-page.tsx
@@ -546,7 +546,9 @@ export function MemorySettingsPage() {
{t.common.loading}
) : error ? (
-
Error: {error.message}
+
+ {t.common.error} {error.message}
+
) : !memory ? (
{t.settings.memory.empty}
diff --git a/frontend/src/components/workspace/settings/skill-settings-page.tsx b/frontend/src/components/workspace/settings/skill-settings-page.tsx
index 593c8279e..95ab1eb4f 100644
--- a/frontend/src/components/workspace/settings/skill-settings-page.tsx
+++ b/frontend/src/components/workspace/settings/skill-settings-page.tsx
@@ -57,7 +57,9 @@ export function SkillSettingsPage({ onClose }: { onClose?: () => void } = {}) {
{t.settings.skills.adminRequired}
) : error ? (
- Error: {error.message}
+
+ {t.common.error} {error.message}
+
) : (
)}
diff --git a/frontend/src/components/workspace/settings/tool-settings-page.tsx b/frontend/src/components/workspace/settings/tool-settings-page.tsx
index 7fd5da326..ccedb7583 100644
--- a/frontend/src/components/workspace/settings/tool-settings-page.tsx
+++ b/frontend/src/components/workspace/settings/tool-settings-page.tsx
@@ -55,7 +55,9 @@ export function ToolSettingsPage() {
{t.settings.tools.adminRequired}
) : error ? (
- Error: {error.message}
+
+ {t.common.error} {error.message}
+
) : (
config &&
)}
diff --git a/frontend/src/core/i18n/locales/en-US.ts b/frontend/src/core/i18n/locales/en-US.ts
index f0c31bcaf..9a4452e3d 100644
--- a/frontend/src/core/i18n/locales/en-US.ts
+++ b/frontend/src/core/i18n/locales/en-US.ts
@@ -38,6 +38,7 @@ export const enUS: Translations = {
custom: "Custom",
notAvailableInDemoMode: "Not available in demo mode",
loading: "Loading...",
+ error: "Error:",
version: "Version",
lastUpdated: "Last updated",
code: "Code",
diff --git a/frontend/src/core/i18n/locales/types.ts b/frontend/src/core/i18n/locales/types.ts
index 9d652958a..133a4ae2f 100644
--- a/frontend/src/core/i18n/locales/types.ts
+++ b/frontend/src/core/i18n/locales/types.ts
@@ -27,6 +27,7 @@ export interface Translations {
custom: string;
notAvailableInDemoMode: string;
loading: string;
+ error: string;
version: string;
lastUpdated: string;
code: string;
diff --git a/frontend/src/core/i18n/locales/zh-CN.ts b/frontend/src/core/i18n/locales/zh-CN.ts
index 0842e4273..7794f9e0e 100644
--- a/frontend/src/core/i18n/locales/zh-CN.ts
+++ b/frontend/src/core/i18n/locales/zh-CN.ts
@@ -38,6 +38,7 @@ export const zhCN: Translations = {
custom: "自定义",
notAvailableInDemoMode: "在演示模式下不可用",
loading: "加载中...",
+ error: "错误:",
version: "版本",
lastUpdated: "最后更新",
code: "代码",
diff --git a/frontend/tests/unit/components/workspace/settings/tool-settings-page.dom.test.tsx b/frontend/tests/unit/components/workspace/settings/tool-settings-page.dom.test.tsx
index 9eee829d1..4a0ecd4ff 100644
--- a/frontend/tests/unit/components/workspace/settings/tool-settings-page.dom.test.tsx
+++ b/frontend/tests/unit/components/workspace/settings/tool-settings-page.dom.test.tsx
@@ -5,6 +5,7 @@ import { ToolSettingsPage } from "@/components/workspace/settings/tool-settings-
const mcpMockState = rs.hoisted(() => ({
isPending: false,
+ error: null as Error | null,
mutate: rs.fn(),
updateIsPending: false,
updateMutate: rs.fn(),
@@ -27,6 +28,7 @@ rs.mock("@/core/i18n/hooks", () => ({
useI18n: () => ({
t: {
common: {
+ error: "Error:",
loading: "Loading",
cancel: "Cancel",
save: "Save",
@@ -67,7 +69,7 @@ rs.mock("@/core/mcp/hooks", () => ({
useMCPConfig: () => ({
config: { mcp_servers: mcpMockState.servers },
isLoading: false,
- error: null,
+ error: mcpMockState.error,
}),
useEnableMCPServer: () => ({
isPending: mcpMockState.isPending,
@@ -118,6 +120,7 @@ function definitionTextbox(): HTMLTextAreaElement {
afterEach(() => {
mcpMockState.isPending = false;
+ mcpMockState.error = null;
mcpMockState.updateIsPending = false;
mcpMockState.mutate.mockReset();
mcpMockState.updateMutate.mockReset();
@@ -126,6 +129,14 @@ afterEach(() => {
});
describe("ToolSettingsPage MCP switches", () => {
+ it("renders a localized load error", () => {
+ mcpMockState.error = new Error("request failed");
+
+ render();
+
+ expect(screen.getByText("Error: request failed")).toBeDefined();
+ });
+
it("disables every switch while a targeted update is pending", () => {
twoServers();
mcpMockState.isPending = true;