AykutSarac/jsoncrack.com · error
Failed to fetch JSON!
Error message
Failed to fetch JSON!
What it means
Toast shown when fetching a remote URL via the Import modal fails. The promise chain is fetch(url).then(res => res.json()) with a single .catch. It fires for network errors, non-2xx responses, CORS rejections, or a response body that is not valid JSON (res.json() throws SyntaxError). All failure modes collapse into the same generic message.
Source
Thrown at apps/www/src/features/modals/ImportModal/index.tsx:31
const [file, setFile] = React.useState<File | null>(null);
const setContents = useFile(state => state.setContents);
const setFormat = useFile(state => state.setFormat);
const handleImportFile = () => {
if (url) {
setFile(null);
toast.loading("Loading...", { id: "toastFetch" });
gaEvent("fetch_url");
return fetch(url)
.then(res => res.json())
.then(json => {
setContents({ contents: JSON.stringify(json, null, 2) });
onClose();
})
.catch(() => toast.error("Failed to fetch JSON!"))
.finally(() => toast.dismiss("toastFetch"));
} else if (file) {
const lastIndex = file.name.lastIndexOf(".");
const format = file.name.substring(lastIndex + 1);
setFormat(format as FileFormat);
file.text().then(text => {
setContents({ contents: text });
setFile(null);
setURL("");
onClose();
});
gaEvent("import_file", { label: format });
}
};
return (View on GitHub (pinned to 3c9af69e23)
Solutions
- Ensure the remote endpoint sends Access-Control-Allow-Origin (or use a CORS proxy in development).
- Check res.ok and res.headers content-type before calling res.json(), and throw a clear error otherwise.
- Log the caught error (it is currently swallowed) to diagnose network vs parse failure.
- Verify the URL returns strict JSON by opening it directly in the browser first.
Example fix
// before
return fetch(url)
.then(res => res.json())
.then(json => { setContents({ contents: JSON.stringify(json, null, 2) }); onClose(); })
.catch(() => toast.error("Failed to fetch JSON!"))
// after — distinguish HTTP vs parse vs network
return fetch(url)
.then(res => {
if (!res.ok) throw new Error(`HTTP ${res.status}`);
return res.json();
})
.then(json => { setContents({ contents: JSON.stringify(json, null, 2) }); onClose(); })
.catch(err => toast.error(err instanceof SyntaxError ? "Response is not valid JSON" : `Failed to fetch JSON: ${err.message}`)) Defensive patterns
Strategy: validation
Validate before calling
// Pre-check reachability and content-type before parsing the body
async function safeFetchJson(url: string): Promise<unknown> {
const res = await fetch(url);
if (!res.ok) throw new Error(`HTTP ${res.status}`);
const type = res.headers.get("content-type") ?? "";
if (!type.includes("json")) throw new Error(`Expected JSON, got ${type}`);
return res.json();
} Type guard
// Confirm a value is JSON-parseable
export function looksLikeJson(text: string): boolean {
try { JSON.parse(text); return true; } catch { return false; }
} Try / catch
// Separate network, HTTP, and parse failures
try {
const json = await safeFetchJson(url);
setContents({ contents: JSON.stringify(json, null, 2) });
} catch (err) {
toast.error(`Failed to fetch JSON: ${err.message}`);
} Prevention
- Ensure the endpoint sends CORS headers (Access-Control-Allow-Origin).
- Check res.ok and content-type before res.json().
- Log the caught error — it is currently swallowed by the empty catch.
When it happens
Trigger: Entering a URL that is unreachable, returns HTML/text instead of JSON, lacks CORS headers (browser blocks the read), returns 4xx/5xx, or requires auth. The catch at ImportModal/index.tsx:31 swallows the error without logging it.
Common situations: Fetching from an API without enabling CORS on the server; pasting a URL to an HTML error page; pointing at a private/local network URL from a deployed site; URL returning JSON wrapped in JSONP or with a BOM.
Related errors
- Failed to fetch document from URL!
- Failed to parse data (${syntaxErrorCount} syntax error(s)).
- Unable to parse data.
- Unable to load file ${files[0].file.name}
- Invalid Schema
AI-assisted analysis of AykutSarac/jsoncrack.com@3c9af69e23 (2026-08-12).
Data as JSON: /api/errors/e39b42025371f076.
Report an issue: GitHub.