Egonex-AI/Understand-Anything · warning · Error

Source unavailable

Error message

Source unavailable

What it means

Thrown by CodeViewer when fetch(fileContentUrl(node.filePath, accessToken)) returns a non-ok response whose JSON body has no usable error field. It is the fallback message for 'the server refused the file-content request but did not tell us why'. Any body.error present is preferred; only when absent does this string surface, and it lands in the viewer's error state (and via setState into the UI).

Source

Thrown at understand-anything-plugin/packages/dashboard/src/components/CodeViewer.tsx:171

    }

    if (accessToken === "__demo__") {
      setState({
        status: "error",
        source: null,
        error: "Source preview is available only when the local dashboard server is running.",
      });
      return;
    }

    const controller = new AbortController();
    setState({ status: "loading", source: null, error: null });

    fetch(fileContentUrl(node.filePath, accessToken), { signal: controller.signal })
      .then(async (res) => {
        const data = (await res.json()) as SourceFile | { error?: string };
        if (!res.ok) {
          throw new Error("error" in data && data.error ? data.error : "Source unavailable");
        }
        setState({ status: "loaded", source: data as SourceFile, error: null });
      })
      .catch((err: unknown) => {
        if (controller.signal.aborted) return;
        setState({
          status: "error",
          source: null,
          error: err instanceof Error ? err.message : String(err),
        });
      });

    return () => controller.abort();
  }, [accessToken, node?.filePath]);

  const highlightedRange = useMemo(() => {
    if (!node?.lineRange) return null;
    return { start: node.lineRange[0], end: node.lineRange[1] };

View on GitHub (pinned to 32944829e7)

Solutions

  1. Confirm the local dashboard dev server is running and reachable (the demo-mode guard at line 155 already steers demo users away; this error means the live fetch itself failed).
  2. Verify the access token matches UA_DASHBOARD_ACCESS_TOKEN on the server.
  3. Open the fileContentUrl directly in the browser to see the raw response body and status — the server often returns a JSON error that the catch swallows.
  4. Confirm node.filePath is within the server's allowlist (paths derived from the loaded graph) — files outside it are refused.
  5. If the file was removed from disk, regenerate the graph so it no longer references the missing path.
Defensive patterns

Strategy: try-catch

Validate before calling

// before opening the viewer, confirm a live server and an allowlisted path
function canFetchSource(accessToken, filePath, graph) {
  if (accessToken === '__demo__') return false; // demo mode has no server
  if (!filePath) return false;
  return graph?.nodes.some((n) => n.filePath === filePath) ?? false; // allowlist
}

Try / catch

fetch(fileContentUrl(node.filePath, accessToken), { signal: controller.signal })
  .then(async (res) => {
    const data = await res.json().catch(() => ({}));
    if (!res.ok) {
      throw new Error((data && data.error) ? data.error : 'Source unavailable');
    }
    return data;
  })
  .catch((err) => {
    if (controller.signal.aborted) return;
    setState({ status: 'error', source: null, error: err.message });
  });

Prevention

When it happens

Trigger: The /file-content.json endpoint returns non-200 (e.g. 403 token mismatch, 404 file not in the graph-derived allowlist, 500 read failure) AND the response body is either not JSON, or is JSON without an error key. The thrown Error('Source unavailable') propagates to the .catch which sets status:'error' and error:'Source unavailable'.

Common situations: Access token mismatch between dashboard client and server. The filePath is outside the graph-derived allowlist the server enforces (so it 404s with an empty/body-less response). Demo mode is not active but the local server is not actually running (fileContentUrl points at an unreachable host). The file was deleted from disk after the graph was built. Symbolic-link / permission issue server-side.

Related errors


AI-assisted analysis of Egonex-AI/Understand-Anything@32944829e7 (2026-08-12). Data as JSON: /api/errors/b4899824f483cb46. Report an issue: GitHub.