wavetermdev/waveterm · error

call ${methodName} failed: ${resp.status} ${resp.statusText}

Error message

call ${methodName} failed: ${resp.status} ${resp.statusText}

What it means

callBackendService received an HTTP response whose resp.ok was false (status outside 200-299) and converts it into a thrown Error containing the status code and status text. This surfaces transport-level backend failures — auth rejection, server error, route not found — for any waveobj service call made through the generic service endpoint.

Source

Thrown at frontend/app/store/wos.ts:128

        args: args,
        uicontext: uiContext,
    };
    // usp is just for debugging (easier to filter URLs)
    const methodName = `${service}.${method}`;
    const usp = new URLSearchParams();
    usp.set("service", service);
    usp.set("method", method);
    const webEndpoint = getWebServerEndpoint();
    if (webEndpoint == null) throw new Error(`cannot call ${methodName}: no web endpoint`);
    const url = webEndpoint + "/wave/service?" + usp.toString();
    const fetchPromise = fetch(url, {
        method: "POST",
        body: JSON.stringify(waveCall),
    });
    const prtn = fetchPromise
        .then((resp) => {
            if (!resp.ok) {
                throw new Error(`call ${methodName} failed: ${resp.status} ${resp.statusText}`);
            }
            return resp.json();
        })
        .then((respData: WebReturnType) => {
            if (respData == null) {
                return null;
            }
            if (respData.updates != null) {
                updateWaveObjects(respData.updates);
            }
            if (respData.error != null) {
                throw new Error(`call ${methodName} error: ${respData.error}`);
            }
            const durationStr = Date.now() - startTs + "ms";
            debugLogBackendCall(methodName, durationStr, args);
            return respData.data;
        });
    return prtn;

View on GitHub (pinned to a4447c1563)

Solutions

  1. Read resp.status in the caught error: 401/403 → re-authenticate; 5xx → check waveserver logs; 404 → fix proxy/endpoint
  2. Restart/verify the waveserver is running and reachable
  3. Re-login or refresh the auth token if 401/403
  4. Confirm the frontend's web server endpoint/port matches the actual backend
  5. Add retry with backoff for transient 502/503 during server restarts

Example fix

// before
try {
    await rpcService.Call(ctx, "waveobj", "GetObject", otype, oid);
} catch (e) {
    console.error(e);
}
// after
try {
    await rpcService.Call(ctx, "waveobj", "GetObject", otype, oid);
} catch (e) {
    const m = String(e).match(/call .* failed: (\d+)/);
    if (m && (m[1] === "502" || m[1] === "503")) {
        await retryWithBackoff(() => rpcService.Call(ctx, "waveobj", "GetObject", otype, oid));
    } else {
        throw e;
    }
}
Defensive patterns

Strategy: retry

Validate before calling

const resp = await fetch(webEndpoint + "/wave/service?" + usp);
if (!resp.ok) {
    console.error("backend service endpoint status:", resp.status);
}
// then rely on callBackendService as usual

Type guard

function isTransportFailure(err: unknown): boolean {
    return /call .* failed: \d+/.test(String(err));
}

Try / catch

try {
    const result = await rpcService.Call(ctx, "waveobj", method, ...args);
} catch (e) {
    const m = String(e).match(/failed: (\d+)/);
    if (m && ["502", "503", "504"].includes(m[1])) {
        return await retryWithBackoff(() => rpcService.Call(ctx, "waveobj", method, ...args));
    }
    if (m && (m[1] === "401" || m[1] === "403")) {
        await reauthenticate();
        return await rpcService.Call(ctx, "waveobj", method, ...args);
    }
    throw e;
}

Prevention

When it happens

Trigger: POST to /wave/service returning 500 (backend exception), 401/403 (auth/token issues), 404 (endpoint/proxy misroute), 502/503 (server down or proxy cannot reach backend).

Common situations: Waveserver crashed or restarting while frontend keeps calling; session/auth token expiry returning 401; dev proxy pointing at the wrong backend port; backend panics on malformed request args.

Understand the failure class

Background: 'Something went wrong' / 'Request failed (500)' / 'HTTP error! status: 404' — what failed HTTP requests actually mean and how to find the real cause — this error's family across 28 libraries.

Related errors


AI-assisted analysis of wavetermdev/waveterm@a4447c1563 (2026-09-01). Data as JSON: /api/errors/fe8dec806264065f. Report an issue: GitHub.