AykutSarac/jsoncrack.com · error

Unable to load graph renderer.

Error message

Unable to load graph renderer.

What it means

In the Chrome extension content script, loadJsonCrackComponent() dynamically imports jsoncrack-react (temporarily shadowing the host page's Worker to let ELK fall back to sync layout). If the import rejects and the thrown value is not an Error instance, this fallback string is stored as componentError. Failures usually stem from the host page's Content Security Policy blocking the module/chunk or blob: worker creation, a missing web_accessible_resources entry, or a bundler that emitted chunk paths the manifest does not expose.

Source

Thrown at apps/chrome-extension/src/content-script.tsx:320

// the graph. That's acceptable for the current target (browser JSON viewers
// on static responses) — revisit if we add SPA support.
function GraphView({ rawJson }: { rawJson: string }) {
  const theme = useSystemTheme();
  const [JSONCrackComponent, setJSONCrackComponent] = useState<JSONCrackComponentType | null>(null);
  const [componentError, setComponentError] = useState<string | null>(null);
  const [selectedNode, setSelectedNode] = useState<NodeData | null>(null);

  useEffect(() => {
    let active = true;

    loadJsonCrackComponent()
      .then(component => {
        if (!active) return;
        setJSONCrackComponent(() => component);
      })
      .catch((error: unknown) => {
        if (!active) return;
        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>;

View on GitHub (pinned to 3c9af69e23)

Solutions

  1. Ensure all dynamically imported chunks are listed in manifest.json web_accessible_resources.
  2. Open DevTools on the host page and read the CSP/blocked-URL directive in the console.
  3. Bundle jsoncrack-react into a single file or load assets from the extension's own origin.
  4. Log the full rejection (including non-Error values) so unknown shapes are diagnosable.

Example fix

// before
.catch((error: unknown) => {
  if (!active) return;
  const message = error instanceof Error ? error.message : "Unable to load graph renderer.";
  setComponentError(message);
});

// after
.catch((error: unknown) => {
  if (!active) return;
  console.error("loadJsonCrackComponent rejected:", error);
  const message = error instanceof Error ? error.message : "Unable to load graph renderer.";
  setComponentError(message);
});
Defensive patterns

Strategy: try-catch

Validate before calling

// Verify the host page CSP allows the extension origin before importing
function cspAllowsExtensionOrigin(): boolean {
  const meta = document.querySelector('meta[http-equiv="Content-Security-Policy"]')?.getAttribute("content") ?? "";
  const header = ""; // script-src from headers is not readable from JS; rely on console errors instead
  return !/script-src[^;]*'none'/.test(meta);
}

Type guard

function isJsonCrackModule(mod: unknown): mod is { JSONCrack: JSONCrackComponentType } {
  return typeof (mod as any)?.JSONCrack === "function" || typeof (mod as any)?.JSONCrack === "object";
}

Try / catch

loadJsonCrackComponent()
  .then(component => { if (active) setJSONCrackComponent(() => component); })
  .catch((error: unknown) => {
    if (!active) return;
    console.error("loadJsonCrackComponent rejected:", error);
    const message = error instanceof Error ? error.message : "Unable to load graph renderer.";
    setComponentError(message);
  });

Prevention

When it happens

Trigger: Extension loaded on a JSON page whose CSP forbids script-src from the extension origin or blob:; extension build missing a chunk file; jsoncrack-react not bundled correctly; manifest web_accessible_resources not exposing the dynamic chunks.

Common situations: Corporate/internal sites with strict CSP; locally loaded file:// JSON; bundler emitting chunk paths the manifest does not expose; version skew between jsoncrack-react and the bundler config.

Related errors


AI-assisted analysis of AykutSarac/jsoncrack.com@3c9af69e23 (2026-08-12). Data as JSON: /api/errors/f2c5043f25c78f02. Report an issue: GitHub.