slopus/happy · error
Server unavailable
Error message
Server unavailable
What it means
setupOfflineReconnection starts a background reconnection loop; when connectivity returns, onReconnected calls api.getOrCreateSession to re-acquire the session. If the API responds but returns a falsy response (session could not be created/retrieved), it throws 'Server unavailable' to signal the swap to a live session failed. It represents a server-side refusal/empty response rather than a client network error.
Source
Thrown at packages/happy-cli/src/utils/setupOfflineReconnection.ts:93
* ```
*/
export function setupOfflineReconnection(opts: SetupOfflineReconnectionOptions): SetupOfflineReconnectionResult {
const { api, sessionTag, metadata, state, response, onSessionSwap } = opts;
let session: ApiSessionClient;
let reconnectionHandle: ReturnType<typeof startOfflineReconnection<ApiSessionClient>> | null = null;
// Note: connectionState.notifyOffline() was already called by api.ts with error details
if (!response) {
// Create a no-op session stub for offline mode using shared utility
session = createOfflineSessionStub(sessionTag);
// Start background reconnection
reconnectionHandle = startOfflineReconnection<ApiSessionClient>({
serverUrl: configuration.serverUrl,
onReconnected: async () => {
const resp = await api.getOrCreateSession({ tag: sessionTag, metadata, state });
if (!resp) throw new Error('Server unavailable');
const realSession = api.sessionSyncClient(resp);
// Notify caller to swap the session reference
onSessionSwap(realSession);
return realSession;
},
onNotify: (msg) => {
// Log to console - this matches Claude's behavior
console.log(msg);
}
});
return { session, reconnectionHandle, isOffline: true };
} else {
session = api.sessionSyncClient(response);
return { session, reconnectionHandle: null, isOffline: false };
}
}
View on GitHub (pinned to b824cd0a46)
Solutions
- Retry — reconnection may succeed once the server stabilizes; the reconnection loop usually re-attempts.
- Inspect server logs / API health for why getOrCreateSession returned no session for that tag.
- Verify client and server versions agree on the getOrCreateSession response shape.
- Restart the CLI session; if the server truly lost the session, create a fresh one.
Example fix
// before
const resp = await api.getOrCreateSession({ tag: sessionTag, metadata, state });
if (!resp) throw new Error('Server unavailable');
// after
const resp = await api.getOrCreateSession({ tag: sessionTag, metadata, state });
if (!resp) throw new Error(`Server did not return a session for tag "${sessionTag}"; check server health and retry`); Defensive patterns
Strategy: retry
Try / catch
reconnectionHandle = startOfflineReconnection<ApiSessionClient>({
...opts,
onReconnected: async () => {
for (let attempt = 1; attempt <= 3; attempt++) {
const resp = await api.getOrCreateSession({ tag: sessionTag, metadata, state });
if (resp) return api.sessionSyncClient(resp);
await new Promise(r => setTimeout(r, 500 * attempt));
}
throw new Error('Server unavailable after retries');
},
}); Prevention
- Retry getOrCreateSession with backoff after reconnection; servers may briefly return empty responses post-outage.
- Confirm client/server API versions match on the response shape.
- Monitor server health and alert on sessions failing to re-acquire.
- Provide a user-facing fallback (create a fresh session) when re-acquisition repeatedly fails.
When it happens
Trigger: After offline reconnection succeeds at the transport level, api.getOrCreateSession({ tag, metadata, state }) resolves to null/undefined — e.g. server returned an empty body, an error envelope parsed to nothing, or the session could not be re-created.
Common situations: Server under load returning empty/failed responses after an outage; session tag/state rejected silently; API version mismatch so the response shape isn't what the client expects; load balancer returning 200 with empty body.
Related errors
- Server unavailable
- Authentication failed
- Happy session lookup authentication expired for legacy accou
- Failed to load Happy sessions: ${error.message}
- request-upload returned an invalid response
AI-assisted analysis of slopus/happy@b824cd0a46 (2026-08-31).
Data as JSON: /api/errors/f0eda3eeb85975c7.
Report an issue: GitHub.