{"record":{"id":"6ef2d43b3e762f2a","repo":"TryGhost/Ghost","slug":"failed-to-fetch-site-data-6ef2d4","errorCode":null,"errorMessage":"Failed to fetch site data","messagePattern":"Failed to fetch site data","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"apps/portal/src/utils/api.js","lineNumber":48,"sourceCode":"        };\n        return fetch(url, options);\n    }\n    const api = {};\n\n    api.site = {\n        read() {\n            const url = endpointFor({type: 'members', resource: 'site'});\n            return makeRequest({\n                url,\n                method: 'GET',\n                headers: {\n                    'Content-Type': 'application/json'\n                }\n            }).then(function (res) {\n                if (res.ok) {\n                    return res.json();\n                } else {\n                    throw new Error('Failed to fetch site data');\n                }\n            });\n        },\n\n        newsletters() {\n            const url = contentEndpointFor({resource: 'newsletters', params: {limit: 100}});\n            return makeRequest({\n                url,\n                method: 'GET',\n                headers: {\n                    'Content-Type': 'application/json'\n                }\n            }).then(function (res) {\n                if (res.ok) {\n                    return res.json();\n                } else {\n                    throw new Error('Failed to fetch site data');\n                }","sourceCodeStart":30,"sourceCodeEnd":66,"githubUrl":"https://github.com/TryGhost/Ghost/blob/47d8b0e2ad2fd4757d3bc45f46c3ac165ff8a1fe/apps/portal/src/utils/api.js#L30-L66","documentation":"Thrown in apps/portal/src/utils/api.js api.site.read() when GET {siteUrl}/members/api/site/ returns non-ok. This is the first call Portal makes on boot to load the site, member, and tiers. The generic message 'Failed to fetch site data' hides the underlying status.","triggerScenarios":"Portal initializes; makeRequest to /members/api/site/ returns 4xx/5xx — common causes: members API disabled, siteUrl mismatch, portal-Integration middleware returns 404, server error bootstrapping members service.","commonSituations":"Ghost server runs an older version that doesn't expose /members/api/site/; the page is served from a different origin than siteUrl (CORS / subdomain mismatch); members feature disabled in labs; reverse proxy returning a cached error page; site in maintenance mode.","solutions":["Open /members/api/site/ directly in a browser and inspect the HTTP status and body.","Confirm siteUrl in the Ghost config matches the origin serving the page (check /ghost/api/config/).","Verify the members/portal feature is enabled and the theme includes the Portal snippet.","Clear any CDN/edge cache that may be serving a stale error response for the members API path."],"exampleFix":"// before\nif (res.ok) { return res.json(); } else { throw new Error('Failed to fetch site data'); }\n\n// after: include status for diagnostics\nif (res.ok) { return res.json(); }\nthrow new Error(`Failed to fetch site data (${res.status} ${res.statusText})`);","handlingStrategy":"retry","validationCode":"// sanity-check the endpoint and origin before boot\nfunction preflightSiteEndpoint(siteUrl) {\n    const u = new URL(siteUrl);\n    if (u.origin !== window.location.origin) {\n        console.warn('siteUrl origin mismatch may cause CORS for /members/api/site/');\n    }\n}","typeGuard":null,"tryCatchPattern":"try {\n    const data = await api.site.read();\n    return data;\n} catch (err) {\n    // err.message === 'Failed to fetch site data'\n    showFatalError('Portal could not load — please refresh. If this persists, contact the site owner.');\n    throw err;\n}","preventionTips":["Keep siteUrl in the Ghost config in sync with the page origin.","Ensure the members/portal feature is enabled on the server.","Do not let CDN/edge caches store /members/api/ responses.","Boot Portal only after the document has a valid session cookie scope."],"tags":["portal","members-api","boot","network","site-config"],"backgroundTag":null,"analyzedSha":"47d8b0e2ad2fd4757d3bc45f46c3ac165ff8a1fe","analyzedAt":"2026-08-13T01:25:26.651Z","schemaVersion":2},"datasetVersion":"2026-08-13T04:17:16.726Z"}