diff --git a/apps/desktop/src/components/boot-failure-overlay.test.tsx b/apps/desktop/src/components/boot-failure-overlay.test.tsx
index e86f987a63..a0dc71b024 100644
--- a/apps/desktop/src/components/boot-failure-overlay.test.tsx
+++ b/apps/desktop/src/components/boot-failure-overlay.test.tsx
@@ -98,4 +98,38 @@ describe('BootFailureOverlay', () => {
restore()
}
})
+
+ it('shows the Nous Cloud down recovery when the backend flags isCloudBackendDown', async () => {
+ const restore = stubDesktop(remoteToken)
+ $desktopBoot.set({
+ error: 'Nous Cloud agent ares-3009.agents.nousresearch.com is down (HTTP 503: server-side fault).',
+ fakeMode: false,
+ isCloudBackendDown: true,
+ message: 'boot failed',
+ phase: 'renderer.error',
+ progress: 40,
+ running: false,
+ statusCode: 503,
+ timestamp: Date.now(),
+ visible: true
+ })
+
+ try {
+ render()
+ // Cloud-specific title + actionable portal guidance instead of the
+ // generic remote-failure copy.
+ expect(await screen.findByText(/Nous Cloud agent is down/i)).toBeTruthy()
+ expect(screen.getByText(/portal\.nousresearch\.com/i)).toBeTruthy()
+ // Cloud-down is a remote failure: local-only Repair is dropped; the
+ // actionable paths are Gateway settings + Use local gateway.
+ expect(screen.queryByRole('button', { name: /repair/i })).toBeNull()
+ expect(screen.getByRole('button', { name: /gateway settings/i })).toBeTruthy()
+ expect(screen.getByRole('button', { name: /use local gateway/i })).toBeTruthy()
+ // The electron-built error message (portal / local mode / Discord) is
+ // still surfaced in the error box.
+ expect(screen.getByText(/ares-3009\.agents\.nousresearch\.com/i)).toBeTruthy()
+ } finally {
+ restore()
+ }
+ })
})
diff --git a/apps/desktop/src/components/boot-failure-overlay.tsx b/apps/desktop/src/components/boot-failure-overlay.tsx
index e479ce5bb9..246b9525df 100644
--- a/apps/desktop/src/components/boot-failure-overlay.tsx
+++ b/apps/desktop/src/components/boot-failure-overlay.tsx
@@ -247,6 +247,11 @@ export function BootFailureOverlay() {
let actions: RecoveryAction[]
let hint: string
+ // The electron boot path flags a Nous Cloud backend-down (502/503/504) with
+ // the structured isCloudBackendDown/statusCode it carries through boot
+ // progress. When set, the recovery screen leads with the cloud-specific
+ // guidance instead of the generic remote-failure copy (#85335).
+ const cloudDown = Boolean(boot.isCloudBackendDown)
if (remoteReauth) {
actions = [
@@ -261,6 +266,12 @@ export function BootFailureOverlay() {
localAction
]
hint = copy.remoteSignInHint(label)
+ } else if (cloudDown) {
+ // A Nous Cloud agent is down — the user cannot restart the managed
+ // instance and Repair is local-only, so the actionable paths are Gateway
+ // settings (switch host / use local), a secondary Retry, and open logs.
+ actions = [settingsAction, { ...retryAction, variant: 'secondary' }, localAction]
+ hint = copy.cloudDownHint
} else if (remoteFailure) {
actions = [settingsAction, { ...retryAction, variant: 'secondary' }, localAction]
hint = copy.remoteFailureHint
@@ -323,10 +334,10 @@ export function BootFailureOverlay() {
- {remoteReauth ? copy.remoteTitle : copy.title}
+ {remoteReauth ? copy.remoteTitle : cloudDown ? copy.cloudDownTitle : copy.title}
- {remoteReauth ? copy.remoteDescription : copy.description}
+ {remoteReauth ? copy.remoteDescription : cloudDown ? copy.cloudDownDescription : copy.description}
diff --git a/apps/desktop/src/i18n/ar.ts b/apps/desktop/src/i18n/ar.ts
index c8ebdf5e97..43a71123e9 100644
--- a/apps/desktop/src/i18n/ar.ts
+++ b/apps/desktop/src/i18n/ar.ts
@@ -85,6 +85,9 @@ export const ar = defineLocale({
retry: 'إعادة المحاولة',
repairInstall: 'إصلاح التثبيت',
useLocalGateway: 'استخدام البوابة المحلية',
+ cloudDownTitle: 'عامل Nous Cloud معطّل',
+ cloudDownDescription: 'يعيد عامل السحابة المُدار من Nous الذي يتصل به هذا البوابة خطأً من الخادم. لا يمكن إعادة تشغيله من هنا — تحقق من حالته، أو بدّل إلى البوابة المحلية، أو احصل على الدعم.',
+ cloudDownHint: 'تحقق من https://portal.nousresearch.com لحالة الخادم، أو استخدم البوابة المحلية أدناه، أو تواصل معنا عبر Discord (discord.gg/NousResearch).',
openLogs: 'فتح السجلات',
repairHint: 'يعيد الإصلاح تشغيل المثبت وقد يستغرق بضع دقائق على جهاز جديد.',
remoteSignInHint: signInLabel =>
diff --git a/apps/desktop/src/i18n/en.ts b/apps/desktop/src/i18n/en.ts
index 64411758e6..6db27de9f7 100644
--- a/apps/desktop/src/i18n/en.ts
+++ b/apps/desktop/src/i18n/en.ts
@@ -102,6 +102,11 @@ export const en: Translations = {
`Signs out of the saved remote browser session, then opens ${signInLabel}. Use local gateway to switch to the bundled backend instead.`,
signOutAndSignIn: 'Sign out & sign in',
remoteFailureHint: 'Check the gateway URL and sign-in under Gateway settings, or switch to the local gateway.',
+ cloudDownTitle: 'Nous Cloud agent is down',
+ cloudDownDescription:
+ 'The Nous-managed cloud agent this gateway connects to is returning a server error. It cannot be restarted from here — check its status, switch to the local gateway, or get support.',
+ cloudDownHint:
+ 'Check https://portal.nousresearch.com for backend status, use the local gateway below, or reach out on Discord (discord.gg/NousResearch).',
hideRecentLogs: 'Hide recent logs',
showRecentLogs: 'Show recent logs',
signedInTitle: 'Signed in',
diff --git a/apps/desktop/src/i18n/ja.ts b/apps/desktop/src/i18n/ja.ts
index c493562019..2ec6066b74 100644
--- a/apps/desktop/src/i18n/ja.ts
+++ b/apps/desktop/src/i18n/ja.ts
@@ -103,6 +103,11 @@ export const ja = defineLocale({
signOutAndSignIn: 'サインアウトして再サインイン',
remoteFailureHint:
'「ゲートウェイ設定」でゲートウェイの URL とサインインを確認するか、ローカルゲートウェイに切り替えてください。',
+ cloudDownTitle: 'Nous Cloud エージェントが停止しています',
+ cloudDownDescription:
+ 'このゲートウェイが接続している Nous 管理のクラウドエージェントがサーバーエラーを返しています。ここから再起動することはできません。ステータスを確認するか、ローカルゲートウェイに切り替えるか、サポートに連絡してください。',
+ cloudDownHint:
+ 'https://portal.nousresearch.com でバックエンドのステータスを確認するか、下のローカルゲートウェイを使用するか、Discord (discord.gg/NousResearch) でご連絡ください。',
hideRecentLogs: '最近のログを非表示',
showRecentLogs: '最近のログを表示',
signedInTitle: 'サインインしました',
diff --git a/apps/desktop/src/i18n/types.ts b/apps/desktop/src/i18n/types.ts
index 1cecefa8a2..a28249ee49 100644
--- a/apps/desktop/src/i18n/types.ts
+++ b/apps/desktop/src/i18n/types.ts
@@ -145,6 +145,9 @@ export interface Translations {
remoteSignInHint: (signInLabel: string) => string
signOutAndSignIn: string
remoteFailureHint: string
+ cloudDownTitle: string
+ cloudDownDescription: string
+ cloudDownHint: string
hideRecentLogs: string
showRecentLogs: string
signedInTitle: string
diff --git a/apps/desktop/src/i18n/zh-hant.ts b/apps/desktop/src/i18n/zh-hant.ts
index ff5145efb8..505e799dc1 100644
--- a/apps/desktop/src/i18n/zh-hant.ts
+++ b/apps/desktop/src/i18n/zh-hant.ts
@@ -100,6 +100,9 @@ export const zhHant = defineLocale({
`先登出已儲存的遠端瀏覽器工作階段,然後開啟${signInLabel}。使用本機閘道可切換至內建後端。`,
signOutAndSignIn: '登出並重新登入',
remoteFailureHint: '在「閘道設定」中檢查閘道 URL 與登入,或切換至本機閘道。',
+ cloudDownTitle: 'Nous Cloud 代理已停機',
+ cloudDownDescription: '此閘道連線的 Nous 託管雲端代理正在回傳伺服器錯誤。無法在此處重新啟動——請檢查其狀態、切換至本機閘道,或取得支援。',
+ cloudDownHint: '請前往 https://portal.nousresearch.com 查看後端狀態,使用下方的本機閘道,或在 Discord (discord.gg/NousResearch) 上與我們聯繫。',
hideRecentLogs: '隱藏最近記錄',
showRecentLogs: '顯示最近記錄',
signedInTitle: '已登入',
diff --git a/apps/desktop/src/i18n/zh.ts b/apps/desktop/src/i18n/zh.ts
index b1dbcb07ae..db548684dd 100644
--- a/apps/desktop/src/i18n/zh.ts
+++ b/apps/desktop/src/i18n/zh.ts
@@ -100,6 +100,9 @@ export const zh: Translations = {
`先退出已保存的远程浏览器会话,然后打开${signInLabel}。也可以使用本地网关切换到随应用提供的后端。`,
signOutAndSignIn: '退出并重新登录',
remoteFailureHint: '在“网关设置”中检查网关 URL 和登录,或切换到本地网关。',
+ cloudDownTitle: 'Nous Cloud 代理已宕机',
+ cloudDownDescription: '此网关连接的 Nous 托管云代理正在返回服务器错误。无法在此处重启——请检查其状态、切换到本地网关或获取支持。',
+ cloudDownHint: '请访问 https://portal.nousresearch.com 查看后端状态,使用下方的本地网关,或在 Discord (discord.gg/NousResearch) 上联系我们。',
hideRecentLogs: '隐藏最近日志',
showRecentLogs: '显示最近日志',
signedInTitle: '已登录',