AykutSarac/jsoncrack.com · error
JSON parsing failed for graph mode.
Error message
JSON parsing failed for graph mode.
What it means
The content script captures the page body text as rawJson and runs JSON.parse in a useMemo. If parsing throws, the component renders this static error div. It means the page body text — which the extension assumed was a JSON document based on document.contentType — is not parseable JSON, even though the content type claimed it was.
Source
Thrown at apps/chrome-extension/src/content-script.tsx:338
const message = error instanceof Error ? error.message : "Unable to load graph renderer.";
setComponentError(message);
});
return () => {
active = false;
};
}, []);
const parsedJson = useMemo(() => {
try {
return JSON.parse(rawJson);
} catch {
return null;
}
}, [rawJson]);
if (parsedJson === null) {
return <div id="jsoncrack-graph-error">JSON parsing failed for graph mode.</div>;
}
if (componentError) {
return <div id="jsoncrack-graph-error">Graph renderer error: {componentError}</div>;
}
if (!JSONCrackComponent) {
return <div id="jsoncrack-graph-status">Loading graph renderer...</div>;
}
return (
<div style={{ width: "100%", height: "100%" }}>
<JSONCrackComponent
json={parsedJson}
theme={theme}
showControls
showGrid
centerOnLayoutView on GitHub (pinned to 3c9af69e23)
Solutions
- Prefer document.documentElement.textContent or fetch the raw body via the background script.
- Trim and attempt a tolerant parse, or strip leading/trailing non-JSON noise.
- Detect an HTML doctype and bail early with a clearer message.
- Fall back to fetch(location.href) for the canonical response body when accessible.
Example fix
// before
const parsedJson = useMemo(() => {
try {
return JSON.parse(rawJson);
} catch {
return null;
}
}, [rawJson]);
// after
const parsedJson = useMemo(() => {
const trimmed = rawJson.trim();
if (!trimmed.startsWith("{") && !trimmed.startsWith("[")) return null;
try {
return JSON.parse(trimmed);
} catch {
return null;
}
}, [rawJson]); Defensive patterns
Strategy: validation
Validate before calling
function tryParseRawJson(raw: string): unknown | null {
const trimmed = raw.trim();
if (!trimmed.startsWith("{") && !trimmed.startsWith("[")) return null;
try {
return JSON.parse(trimmed);
} catch {
return null;
}
} Type guard
function looksLikeJsonBody(raw: string): boolean {
const t = raw.trim();
return (t.startsWith("{") && t.endsWith("}")) || (t.startsWith("[") && t.endsWith("]"));
} Try / catch
const parsedJson = useMemo(() => tryParseRawJson(rawJson), [rawJson]);
if (parsedJson === null) {
return <div id="jsoncrack-graph-error">JSON parsing failed for graph mode.</div>;
} Prevention
- Prefer document.documentElement.textContent over innerText, which can include injected UI text.
- Detect an HTML doctype early and skip rendering to avoid confusing parse-failure messages.
- Consider fetching the canonical body via the background script to avoid DOM mutations by other extensions.
When it happens
Trigger: Another JSON-viewer extension already prettified/wrapped the body text; document.body.innerText includes injected UI text around the JSON; truncated or partial response; contentType spoofed; an HTML error page served with a JSON content-type header.
Common situations: Conflicting JSON-viewer extension mutating the DOM; server returning 200 with an HTML body but a JSON content-type; streaming/partial response cut off.
Related errors
- Unable to load graph renderer.
- Graph renderer error: {componentError}
- Canvas not found.
- error
- json, error
AI-assisted analysis of AykutSarac/jsoncrack.com@3c9af69e23 (2026-08-12).
Data as JSON: /api/errors/6d5564cfe3b098c1.
Report an issue: GitHub.