{"record":{"id":"454ec33ab7d0e6b8","repo":"Graphify-Labs/graphify","slug":"error-sections-file-must-contain-a-json-array-p","errorCode":null,"errorMessage":"ERROR: sections file must contain a JSON array: {path}","messagePattern":"ERROR: sections file must contain a JSON array: (.+?)","errorType":"exception","errorClass":"SystemExit","httpStatus":null,"severity":"error","filePath":"graphify/callflow_html.py","lineNumber":331,"sourceCode":"    if isinstance(data.get(\"labels\"), dict):\n        data = data[\"labels\"]\n    if isinstance(data.get(\"communities\"), dict):\n        data = data[\"communities\"]\n    labels = {}\n    for key, value in data.items():\n        if isinstance(value, dict):\n            value = first_present(value, \"label\", \"name\", \"title\", default=key)\n        labels[str(key)] = str(value)\n    return labels\n\n\ndef load_sections(path: str | Path | None) -> list:\n    \"\"\"Load section definitions from JSON file.\"\"\"\n    data = read_json(path, default=[])\n    if isinstance(data, dict) and isinstance(data.get(\"sections\"), list):\n        data = data[\"sections\"]\n    if not isinstance(data, list):\n        raise SystemExit(f\"ERROR: sections file must contain a JSON array: {path}\")\n    return data\n\n\ndef load_report(path: str | Path | None) -> str:\n    \"\"\"Load GRAPH_REPORT.md if it exists.\"\"\"\n    if path and os.path.exists(path):\n        return Path(path).read_text(encoding=\"utf-8\")\n    return \"\"\n\n\n# ──────────────────────────────────────────────\n# 3. Mermaid-safe label helpers\n# ──────────────────────────────────────────────\n\ndef safe_mermaid_text(text: str) -> str:\n    \"\"\"Sanitize text for use inside a Mermaid node label.\n\n    Replaces characters that Mermaid interprets as syntax:","sourceCodeStart":313,"sourceCodeEnd":349,"githubUrl":"https://github.com/Graphify-Labs/graphify/blob/7fe58b0b0f3873be9a21c30106b8b8527c353aa6/graphify/callflow_html.py#L313-L349","documentation":"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/.","triggerScenarios":"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.","commonSituations":"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.","solutions":["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.","Diff node counts (existing graph.json vs new graph) to confirm the shrink is real, then check extraction/detection sidecars for skipped files.","Clean stale artifacts: remove graphify-out/graph.json (and stray .graphify_analysis.json at cwd) before rebuilding.","Align paths by upgrading to the current fragment, which keeps every sidecar under graphify-out/."],"exampleFix":"# before\n/graphify update .\n# ERROR: refused to shrink ... fewer nodes ...\n\n# after\nrm -f graphify-out/graph.json .graphify_analysis.json\n/graphify build --force .","handlingStrategy":"validation","validationCode":"import json\nfrom pathlib import Path\n\nold_n = len(json.loads(Path('graphify-out/graph.json').read_text(encoding='utf-8')).get('nodes', []))\nnew_n = len(json.loads(Path('graphify-out/.graphify_extract.json').read_text(encoding='utf-8')).get('nodes') or [])\nif new_n < old_n:\n    raise SystemExit(f'planned shrink {old_n}->{new_n}: full rebuild (with --force) required')","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Detect shrinks before export and rebuild fully (--force) when intended.","Clean stray cwd-level .graphify_analysis.json left by this legacy fragment to avoid mixed-run state.","Keep INPUT_PATH stable between builds so node sets are comparable.","Check skip lists when the count drops without file deletions."],"tags":["graphify","aider","shrink-guard","export","legacy-paths"],"backgroundTag":null,"analyzedSha":"7fe58b0b0f3873be9a21c30106b8b8527c353aa6","analyzedAt":"2026-08-14T19:23:21.323Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}