TryGhost/Ghost · warning · Error
Failed to fetch changelog: ${response.status}
Error message
Failed to fetch changelog: ${response.status} What it means
useChangelog is a TanStack Query useQuery hook that fetches https://ghost.org/changelog.json to populate the in-admin 'What's New' panel. If the fetch resolves but response.ok is false (HTTP 4xx/5xx), it throws with the status code. The error surfaces as the query's error state and triggers React Query's retry/errorBoundary behavior.
Source
Thrown at apps/admin/src/whats-new/hooks/use-changelog.ts:51
posts: z.array(ChangelogEntrySchema).default([]),
changelogUrl: z.string().url().default("https://ghost.org/changelog"),
})
.transform((data) => ({
entries: data.posts,
changelogUrl: data.changelogUrl,
}));
export type RawChangelogResponse = z.input<typeof ChangelogResponseSchema>;
export type ChangelogResponse = z.output<typeof ChangelogResponseSchema>;
export const useChangelog = () =>
useQuery({
queryKey: ["changelog"],
queryFn: async () => {
const response = await fetch("https://ghost.org/changelog.json");
if (!response.ok) {
throw new Error(`Failed to fetch changelog: ${response.status}`);
}
const data = (await response.json()) as unknown;
return ChangelogResponseSchema.parse(data);
},
staleTime: Infinity,
});
View on GitHub (pinned to 47d8b0e2ad)
Solutions
- Check browser DevTools Network tab for the actual status and response body of the changelog.json request.
- If behind a proxy, ensure ghost.org is allowlisted or disable the changelog panel in offline environments.
- React Query retries by default (3 attempts) — if transient, the error clears on retry; for permanent blocks, suppress the panel via the feature flag or conditional rendering on query error.
- If the endpoint moved, update the URL in use-changelog.ts:48.
Defensive patterns
Strategy: fallback
Try / catch
// useChangelog uses React Query; consume the error state in the component:
const {data, error, isLoading} = useChangelog();
if (error) {
// render the panel in a degraded/hidden state
return null;
} Prevention
- Gate the 'What's New' panel behind the query's success state so a fetch failure does not break the admin.
- Ensure network egress to ghost.org is allowed in air-gapped/proxied environments or disable the panel there.
- Rely on React Query's default retry (3 attempts) for transient failures; do not add manual retries that double the load.
When it happens
Trigger: The fetch to ghost.org/changelog.json returns a non-2xx status. Common causes: a 404 if the endpoint path changes, a 403 if Cloudflare blocks the request (geo or bot rules), a 5xx during a Ghost infra outage, or a captive-portal/proxy returning a 200-shaped error page that still has ok=false. Network failures (fetch rejects) produce a different error (TypeError) before this line.
Common situations: Corporate proxy or firewall blocks or rewrites the request. Ghost infra is temporarily down. The admin is loaded in an environment without internet (air-gapped, local-only dev). A browser extension intercepts the request. DNS resolution returns a captive portal page.
Related errors
- Failed to fetch site data
- Failed to fetch site data
- Failed to fetch comments
- Failed to fetch replies
- Failed to add comment
AI-assisted analysis of TryGhost/Ghost@47d8b0e2ad (2026-08-13).
Data as JSON: /api/errors/d3324c07afdeecf4.
Report an issue: GitHub.