AykutSarac/jsoncrack.com · error

Graph renderer error: {componentError}

Error message

Graph renderer error: {componentError}

What it means

Rendered when componentError state is non-null, i.e. loadJsonCrackComponent() rejected (see the renderer-load failure). The div interpolates the captured message, often containing the CSP blocked-URL or chunk-load detail. This is the visible symptom the user sees in place of the graph.

Source

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

    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
        centerOnLayout
        onNodeClick={node => setSelectedNode(node)}
        renderNodeLimitExceeded={() => <NodeLimitUpgrade />}
      />
      <NodeModal nodeData={selectedNode} onClose={() => setSelectedNode(null)} />

View on GitHub (pinned to 3c9af69e23)

Solutions

  1. Read the interpolated message — it usually contains the CSP/blocked-URL detail.
  2. Apply the renderer-load fixes (web_accessible_resources, single-file bundle, extension-origin assets).
  3. Add a retry affordance that clears the memoized jsonCrackComponentPromise and re-imports.
  4. Distinguish 'import failed' from 'Worker blocked' so guidance can be targeted.

Example fix

// before
const loadJsonCrackComponent = async () => {
  if (jsonCrackComponentPromise) return jsonCrackComponentPromise;
  jsonCrackComponentPromise = (async () => { /* import */ })();
  return jsonCrackComponentPromise;
};

// after
const loadJsonCrackComponent = async () => {
  if (jsonCrackComponentPromise) return jsonCrackComponentPromise;
  jsonCrackComponentPromise = (async () => { /* import */ })();
  try {
    return await jsonCrackComponentPromise;
  } catch (e) {
    jsonCrackComponentPromise = null; // allow retry
    throw e;
  }
};
Defensive patterns

Strategy: retry

Validate before calling

// Allow the memoized import promise to be retried after a failure
function resetLoaderOnFailure() {
  jsonCrackComponentPromise = null;
}

Try / catch

try {
  return await jsonCrackComponentPromise;
} catch (e) {
  jsonCrackComponentPromise = null; // allow retry on next user action
  throw e;
}

Prevention

When it happens

Trigger: Same root causes as the renderer-load failure: CSP block, missing chunk, bundler/manifest misconfiguration, or a side effect of the temporary Worker shadowing.

Common situations: Same as the renderer-load failure; corporate sites with strict CSP; extension built without exposing chunks via web_accessible_resources.

Related errors


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