wavetermdev/waveterm · error

Failed to fetch config: ${configResponse.statusText}

Error message

Failed to fetch config: ${configResponse.statusText}

What it means

The builder config/data tab loads both /api/config and /api/data from the builder backend in parallel. If the config fetch resolves with a non-2xx status, this error surfaces the HTTP statusText so the tab can show the load failure instead of parsing an error body as JSON.

Source

Thrown at frontend/builder/tabs/builder-configdatatab.tsx:98

    const isRunning = builderStatus?.status === "running" && builderStatus?.port && builderStatus.port !== 0;

    const fetchData = useCallback(async () => {
        if (!isRunning || !builderStatus?.port) {
            return;
        }

        setState((prev) => ({ ...prev, isLoading: true, error: null }));

        try {
            const baseUrl = `http://localhost:${builderStatus.port}`;

            const [configResponse, dataResponse] = await Promise.all([
                fetch(`${baseUrl}/api/config`),
                fetch(`${baseUrl}/api/data`),
            ]);

            if (!configResponse.ok) {
                throw new Error(`Failed to fetch config: ${configResponse.statusText}`);
            }
            if (!dataResponse.ok) {
                throw new Error(`Failed to fetch data: ${dataResponse.statusText}`);
            }

            const config = await configResponse.json();
            const data = await dataResponse.json();

            setState({
                config,
                data,
                error: null,
                isLoading: false,
            });
        } catch (err) {
            setState({
                config: null,
                data: null,

View on GitHub (pinned to a4447c1563)

Solutions

  1. Check the statusText/status: 404 → wrong baseUrl or missing route; 500 → backend exception; 401/403 → auth.
  2. Confirm the builder backend is running and reachable at baseUrl (curl {baseUrl}/api/config).
  3. Update frontend and backend together so the /api/config route matches.
  4. Inspect backend logs for the failing request.

Example fix

// before
const [configResponse, dataResponse] = await Promise.all([
  fetch(`${baseUrl}/api/config`),
  fetch(`${baseUrl}/api/data`),
]);
if (!configResponse.ok) throw new Error(`Failed to fetch config: ${configResponse.statusText}`);
// after — fail fast with actionable status and check server first
const baseUrl = await ensureBuilderServerRunning(); // start server if not up
const res = await fetch(`${baseUrl}/api/config`);
if (!res.ok) throw new Error(`Config fetch failed: HTTP ${res.status} ${res.statusText} at ${baseUrl}/api/config`);
Defensive patterns

Strategy: try-catch

Validate before calling

async function assertEndpoint(baseUrl: string) {
  try {
    const res = await fetch(`${baseUrl}/api/config`);
    return res.ok;
  } catch {
    return false; // server unreachable
  }
}
if (!(await assertEndpoint(baseUrl))) throw new Error(`builder backend unreachable at ${baseUrl}`);

Try / catch

try {
  await loadConfigAndData(baseUrl);
} catch (e) {
  if (String(e.message).startsWith("Failed to fetch config")) {
    setState({ error: `builder backend issue: ${e.message} — is the server running at ${baseUrl}?` });
    return;
  }
  throw e;
}

Prevention

When it happens

Trigger: The GET {baseUrl}/api/config request returns 404/500/502 etc. — backend not running at baseUrl, route renamed/removed, or a proxy/gateway returning an error page.

Common situations: Builder server not started or crashed, wrong baseUrl/port in the tab configuration, API version mismatch between frontend and backend, auth middleware rejecting the request.

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/bf431365ef2355b0. Report an issue: GitHub.