Graphify-Labs/graphify · error · SystemExit

ERROR: sections file must contain a JSON array: {path}

Error message

ERROR: sections file must contain a JSON array: {path}

What it means

The older-variant shrink-guard in the aider fragment (tools/skillgen/fragments/core/aider.md:428). to_json(G, communities, 'graphify-out/graph.json') returns False when the existing graph.json has more nodes; the script prints the 'fewer nodes than the existing graph' message (older wording, no #479 tag, no --force mention) and exits 1 before writing GRAPH_REPORT.md. Note this fragment also writes the analysis sidecar to Path('.graphify_analysis.json') at cwd, unlike newer variants that use graphify-out/.

Source

Thrown at graphify/callflow_html.py:331

    if isinstance(data.get("labels"), dict):
        data = data["labels"]
    if isinstance(data.get("communities"), dict):
        data = data["communities"]
    labels = {}
    for key, value in data.items():
        if isinstance(value, dict):
            value = first_present(value, "label", "name", "title", default=key)
        labels[str(key)] = str(value)
    return labels


def load_sections(path: str | Path | None) -> list:
    """Load section definitions from JSON file."""
    data = read_json(path, default=[])
    if isinstance(data, dict) and isinstance(data.get("sections"), list):
        data = data["sections"]
    if not isinstance(data, list):
        raise SystemExit(f"ERROR: sections file must contain a JSON array: {path}")
    return data


def load_report(path: str | Path | None) -> str:
    """Load GRAPH_REPORT.md if it exists."""
    if path and os.path.exists(path):
        return Path(path).read_text(encoding="utf-8")
    return ""


# ──────────────────────────────────────────────
# 3. Mermaid-safe label helpers
# ──────────────────────────────────────────────

def safe_mermaid_text(text: str) -> str:
    """Sanitize text for use inside a Mermaid node label.

    Replaces characters that Mermaid interprets as syntax:

View on GitHub (pinned to 7fe58b0b0f)

Solutions

  1. Run a full rebuild to be safe, exactly as the message says — for the modern CLI that is a full build with --force so graph.json is overwritten.
  2. Diff node counts (existing graph.json vs new graph) to confirm the shrink is real, then check extraction/detection sidecars for skipped files.
  3. Clean stale artifacts: remove graphify-out/graph.json (and stray .graphify_analysis.json at cwd) before rebuilding.
  4. Align paths by upgrading to the current fragment, which keeps every sidecar under graphify-out/.

Example fix

# before
/graphify update .
# ERROR: refused to shrink ... fewer nodes ...

# after
rm -f graphify-out/graph.json .graphify_analysis.json
/graphify build --force .
Defensive patterns

Strategy: validation

Validate before calling

import json
from pathlib import Path

old_n = len(json.loads(Path('graphify-out/graph.json').read_text(encoding='utf-8')).get('nodes', []))
new_n = len(json.loads(Path('graphify-out/.graphify_extract.json').read_text(encoding='utf-8')).get('nodes') or [])
if new_n < old_n:
    raise SystemExit(f'planned shrink {old_n}->{new_n}: full rebuild (with --force) required')

Prevention

When it happens

Trigger: Rebuilding produced a graph smaller than the existing graphify-out/graph.json: corpus files deleted, files skipped during re-extraction, or a stale larger graph.json. Mixed path conventions (graph.json under graphify-out/ but analysis sidecar at cwd) can also leave artifacts from different runs interacting.

Common situations: Incremental update after pruning; branch switch to a smaller tree; legacy graphify-out from a bigger build; running from a different directory so cwd-sidecar state diverges from graphify-out state.

Related errors


AI-assisted analysis of Graphify-Labs/graphify@7fe58b0b0f (2026-08-14). Data as JSON: /api/errors/454ec33ab7d0e6b8. Report an issue: GitHub.