slopus/happy · error

Failed to load Happy sessions: ${error.message}

Error message

Failed to load Happy sessions: ${error.message}

What it means

fetchSessions wraps its Axios API call; any non-401 Axios error (network failure, DNS error, 5xx, timeout, TLS problem) is rethrown as `Failed to load Happy sessions: <axios message>`. Non-Axios errors are rethrown untouched. It distinguishes transport/server problems from the dedicated 401 auth-expired error.

Source

Thrown at packages/happy-cli/src/resume/resolveHappySession.ts:146

    return parseResumableMetadata(session.id, metadata);
}

async function fetchSessions(credentials: LocalHappyAgentCredentials): Promise<RawSession[]> {
    try {
        const response = await axios.get(`${configuration.serverUrl}/v1/sessions`, {
            headers: {
                Authorization: `Bearer ${credentials.token}`,
                'X-Happy-Client': `cli-coding-session/${configuration.currentCliVersion}`,
            },
        });
        return (response.data as { sessions: RawSession[] }).sessions;
    } catch (error) {
        if (error instanceof AxiosError) {
            if (error.response?.status === 401) {
                throw new Error('Happy session lookup authentication expired for legacy account credentials.');
            }
            throw new Error(`Failed to load Happy sessions: ${error.message}`);
        }
        throw error;
    }
}

export async function resolveHappySession(sessionId: string): Promise<ResumableHappySession> {
    const credentials = readAgentCredentials();
    const sessions = await fetchSessions(credentials);
    const matched = resolveSessionRecordByPrefix(sessions, sessionId);
    return {
        id: matched.id,
        active: matched.active,
        metadata: decryptSessionMetadata(matched, credentials),
    };
}

export async function resolveReconnectableSession(sessionId: string): Promise<ReconnectableHappySession> {
    const credentials = readAgentCredentials();

View on GitHub (pinned to b824cd0a46)

Solutions

  1. Read the wrapped axios message: check internet connectivity and whether the API host resolves/reachable (curl the serverUrl).
  2. Check Happy service status / wait out a 5xx outage and retry.
  3. Fix proxy/VPN/firewall settings if the endpoint is blocked; set HTTPS_PROXY if required.
  4. Verify serverUrl configuration points at the correct Happy API endpoint.

Example fix

// before
$ happy resume <id>  // Failed to load Happy sessions: getaddrinfo api.example.com ENOTFOUND
// after
$ curl -I https://api.happy.com/health   # diagnose connectivity
$ # fix VPN/DNS/proxy, or configure correct serverUrl, then retry
Defensive patterns

Strategy: retry

Validate before calling

// Pre-flight connectivity check:
const ok = await fetch(serverUrl + '/health').then(r => r.ok).catch(() => false);
if (!ok) { console.error('Happy API unreachable — check network/VPN'); process.exit(1); }

Try / catch

try {
  const session = await resolveHappySession(id);
} catch (err) {
  if ((err as Error).message.startsWith('Failed to load Happy sessions:')) {
    // exponential-backoff retry loop for transient network/5xx; surface axios message
  } else throw err;
}

Prevention

When it happens

Trigger: Calling fetchSessions when the Happy API endpoint is unreachable (no network, DNS failure, wrong serverUrl), returns 500/502/503, times out, or TLS fails — any AxiosError with status !== 401.

Common situations: Laptop offline or behind a captive portal/VPN; corporate proxy or firewall blocking the endpoint; API outage; custom serverUrl misconfigured; DNS resolver issues.

Understand the failure class

Background: "API request failed": what wrapped HTTP errors from external APIs mean and how to find the real cause — this error's family across 29 libraries.

Related errors


AI-assisted analysis of slopus/happy@b824cd0a46 (2026-08-31). Data as JSON: /api/errors/5555d4d647479685. Report an issue: GitHub.