GitbookIO/gitbook · error · DataFetcherError

Failed to fetch OpenAPI file

Error message

Failed to fetch OpenAPI file

What it means

fetchFilesystemNoCache downloads an OpenAPI/Swagger file with fetch (no-store) and throws DataFetcherError('Failed to fetch OpenAPI file', response.status) whenever the response is not ok. The HTTP status of the upstream fetch becomes the error status, so a 404 file gives a 404 error and a 500 origin gives a 500.

Source

Thrown at packages/gitbook/src/lib/openapi/fetch.ts:120

        // If the error is not an OpenAPIParseError or DataFetcherError,
        // we assume it's an unknown error and return a generic error.
        console.error('Unknown error while fetching OpenAPI file:', error);
        return { error: { code: 'invalid' as const, message: 'Unknown error' } };
    }
}

async function fetchFilesystemNoCache(url: string) {
    console.log(url);
    // Wrap the raw string to prevent invalid URLs from being passed to fetch.
    // This can happen if the URL has whitespace, which is currently handled differently by Cloudflare's implementation of fetch:
    // https://github.com/cloudflare/workerd/issues/1957
    const response = await fetch(new URL(url), {
        ...noCacheFetchOptions,
        cache: 'no-store',
    });

    if (!response.ok) {
        throw new DataFetcherError('Failed to fetch OpenAPI file', response.status);
    }

    const text = await response.text();
    const { filesystem } = await parseOpenAPI({ value: text, rootURL: url });
    const richFilesystem = await enrichFilesystem(filesystem);

    return richFilesystem;
}

View on GitHub (pinned to db67585ee2)

Solutions

  1. curl -I the exact spec URL from your deployment environment to see the real status code
  2. Fix or update the source URL in the OpenAPI block to a publicly reachable endpoint
  3. If the spec requires auth, expose it through a proxy that injects credentials, or make it public
  4. Catch DataFetcherError around fetchFilesystem and render a friendly 'spec unavailable' state instead of failing the page

Example fix

// before
const filesystem = await fetchFilesystem(url);

// after
try {
    const filesystem = await fetchFilesystem(url);
} catch (e) {
    if (e instanceof DataFetcherError && e.message === 'Failed to fetch OpenAPI file') {
        return renderSpecUnavailable(url);
    }
    throw e;
}
Defensive patterns

Strategy: try-catch

Validate before calling

// Pre-flight the spec URL from the same environment
const head = await fetch(url, { method: 'HEAD' });
if (!head.ok) throw new Error(`Spec unreachable: ${head.status}`);

Type guard

function isOpenAPIFetchError(e: unknown): e is DataFetcherError {
    return e instanceof DataFetcherError && e.message === 'Failed to fetch OpenAPI file';
}

Try / catch

try {
    const fs = await fetchFilesystem(url);
} catch (e) {
    if (isOpenAPIFetchError(e)) {
        return renderSpecUnavailable(url, e.status);
    }
    throw e;
}

Prevention

When it happens

Trigger: Rendering an OpenAPI block whose source URL returns non-2xx — file moved or deleted (404), private/gated requiring auth (401/403), origin down (5xx), or DNS/TLS failures that surface as non-ok proxy responses.

Common situations: Spec URLs pointing to internal hosts unreachable from the deployment (Vercel/Cloudflare can't reach localhost or VPN-only hosts); a repo renamed so raw.githubusercontent links 404; auth-protected spec files; typos in the URL configured in the GitBook block.

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 GitbookIO/gitbook@db67585ee2 (2026-08-28). Data as JSON: /api/errors/a8b4f14bc5d8d438. Report an issue: GitHub.