wavetermdev/waveterm · error

Failed to fetch data: ${dataResponse.statusText}

Error message

Failed to fetch data: ${dataResponse.statusText}

What it means

Same parallel fetch flow as the config error, but for /api/data: if the data endpoint responds with a non-2xx status, this error is thrown. Config may have succeeded while data failed, pointing at the data endpoint specifically.

Source

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

        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,
                error: err instanceof Error ? err.message : String(err),
                isLoading: false,
            });

View on GitHub (pinned to a4447c1563)

Solutions

  1. Check the specific status: 500 → backend data error (check server logs); 404 → route/baseUrl mismatch; 502/504 → upstream/proxy issue.
  2. Verify the backend's data source (file/db) exists and is readable.
  3. Curl {baseUrl}/api/data directly to reproduce outside the UI.
  4. Handle config-ok/data-failed gracefully: keep cached data and surface a retry instead of blanking the tab.

Example fix

// before
const data = await dataResponse.json(); // assumes ok
// after
if (!dataResponse.ok) {
  console.error(`data endpoint failed: HTTP ${dataResponse.status}`);
  throw new Error(`Failed to fetch data: HTTP ${dataResponse.status} ${dataResponse.statusText}`);
}
const data = await dataResponse.json();
Defensive patterns

Strategy: try-catch

Validate before calling

const res = await fetch(`${baseUrl}/api/data`);
if (!res.ok) {
  console.error(`/api/data unhealthy: HTTP ${res.status}`);
  throw new Error(`data endpoint unavailable at ${baseUrl} (HTTP ${res.status})`);
}

Try / catch

try {
  await loadConfigAndData(baseUrl);
} catch (e) {
  if (String(e.message).startsWith("Failed to fetch data")) {
    // keep last-known-good data and offer retry
    setState({ error: e.message, staleData: true });
    return;
  }
  throw e;
}

Prevention

When it happens

Trigger: GET {baseUrl}/api/data returns non-2xx — data store unavailable/corrupt on the backend, the data route erroring, or a proxy returning 502/504 while config (cached/static) still succeeds.

Common situations: Backend's data file/database missing or locked, backend exception while serializing data, partial outage of the builder service behind a reverse proxy.

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