diff --git a/docs/swarm/ui.md b/docs/swarm/ui.md
index 3ee7479b..05fdf3e3 100644
--- a/docs/swarm/ui.md
+++ b/docs/swarm/ui.md
@@ -435,7 +435,10 @@ name that already holds an account; delete that account first to replace it.
The agent's detail panel lists its linked accounts under **accounts**, one row
per account: kind, name and host. Opening an agent makes one request,
`GET /api/hives/{hive}/agents/{agent}/linked-accounts`, which returns every
-account of that agent as names and hosts and never a credential.
+account of that agent as names and hosts and never a credential. When the panel
+fails to read the accounts, the inference settings or the resource caps, it
+shows the reason as text. A list the panel already loaded stays on screen
+beneath the error.
| kind | one row per | name | host |
| ------- | ------------------------------------------- | ----------- | ------------------------ |
diff --git a/frontend/packages/swarm-ui/src/agent/detail/AgentInference.tsx b/frontend/packages/swarm-ui/src/agent/detail/AgentInference.tsx
index f59c520e..5fb83a1c 100644
--- a/frontend/packages/swarm-ui/src/agent/detail/AgentInference.tsx
+++ b/frontend/packages/swarm-ui/src/agent/detail/AgentInference.tsx
@@ -205,21 +205,23 @@ export function AgentInference({ agent }: { agent: string }) {
};
}, [agent, reload]);
- if (error) {
- return (
-
- );
+ // Shown as text, not a hover title. Settings already loaded stay under a
+ // failed refetch, so a save that worked is not hidden by a read that did not.
+ const errorPanel = error ? (
+
+ ) : null;
+ if (view === null) {
+ return errorPanel ?? …;
}
- if (view === null) return …;
const { configured, effective } = view;
const swarmModels = configured?.subagent_models ?? [];
return (
+ {errorPanel}
-
{effective ? (
diff --git a/frontend/packages/swarm-ui/src/agent/detail/AgentLimits.tsx b/frontend/packages/swarm-ui/src/agent/detail/AgentLimits.tsx
index da7fb392..3860e3d9 100644
--- a/frontend/packages/swarm-ui/src/agent/detail/AgentLimits.tsx
+++ b/frontend/packages/swarm-ui/src/agent/detail/AgentLimits.tsx
@@ -114,19 +114,18 @@ export function AgentLimits({ agent }: { agent: string }) {
};
}, [agent, reload]);
- if (error) {
- return (
-
- );
+ // Shown as text, not a hover title. Caps already loaded stay under a
+ // failed refetch, so a save that worked is not hidden by a read that did not.
+ const errorPanel = error ? (
+
+ ) : null;
+ if (caps === null) {
+ return errorPanel ?? …;
}
- if (caps === null) return …;
return (
+ {errorPanel}
-
diff --git a/frontend/packages/swarm-ui/src/agent/detail/LinkedAccounts.tsx b/frontend/packages/swarm-ui/src/agent/detail/LinkedAccounts.tsx
index daa3eed7..fa1eaf25 100644
--- a/frontend/packages/swarm-ui/src/agent/detail/LinkedAccounts.tsx
+++ b/frontend/packages/swarm-ui/src/agent/detail/LinkedAccounts.tsx
@@ -156,21 +156,26 @@ export function LinkedAccounts({
);
- if (error) {
- return (
-
- );
+ // Shown as text, not a hover title. A list already loaded stays under a
+ // failed refetch, so a link or delete that worked is not hidden by a read
+ // that did not.
+ const errorPanel = error ? (
+
+ ) : null;
+ if (accounts === null) {
+ return errorPanel ?? …;
}
- if (accounts === null) return …;
if (accounts.length === 0) {
- return none linked;
+ return (
+ <>
+ {errorPanel}
+ none linked
+ >
+ );
}
return (
<>
+ {errorPanel}