{"record":{"id":"ec9656d3ceebc7f5","repo":"Graphify-Labs/graphify","slug":"error-invalid-json-in-path-exc","errorCode":null,"errorMessage":"ERROR: invalid JSON in {path}: {exc}","messagePattern":"ERROR: invalid JSON in (.+?): (.+?)","errorType":"exception","errorClass":"SystemExit","httpStatus":null,"severity":"error","filePath":"graphify/callflow_html.py","lineNumber":104,"sourceCode":"@media (max-width: 768px) { .container { padding: 16px; } h1 { font-size: 1.8rem; } }\n\"\"\"\n\n\n# ──────────────────────────────────────────────\n# 2. Data loading and normalization helpers\n# ──────────────────────────────────────────────\n\ndef read_json(path: str | Path, default=None):\n    \"\"\"Read JSON with a useful error message.\"\"\"\n    if not path:\n        return default\n    path = Path(path)\n    if not path.exists():\n        return default\n    try:\n        return json.loads(path.read_text(encoding=\"utf-8\"))\n    except json.JSONDecodeError as exc:\n        raise SystemExit(f\"ERROR: invalid JSON in {path}: {exc}\") from exc\n\n\ndef first_present(mapping: dict, *keys, default=None):\n    \"\"\"Return the first non-empty value for any candidate key.\"\"\"\n    for key in keys:\n        if key in mapping and mapping[key] not in (None, \"\"):\n            return mapping[key]\n    return default\n\n\ndef first_list(*values) -> list:\n    \"\"\"Return the first list from a set of possible schema locations.\"\"\"\n    for value in values:\n        if isinstance(value, list):\n            return value\n    return []\n\n","sourceCodeStart":86,"sourceCodeEnd":122,"githubUrl":"https://github.com/Graphify-Labs/graphify/blob/7fe58b0b0f3873be9a21c30106b8b8527c353aa6/graphify/callflow_html.py#L86-L122","documentation":"The empty-graph fail-fast guard in the core graphify skill fragment (tools/skillgen/fragments/core/core.md:354). It prints both the 'Graph is empty' line and the 'Possible causes' line, then raises SystemExit(1) immediately after build_from_json() — before cluster/score/export run — so an empty extraction cannot overwrite a healthy graph.json, GRAPH_REPORT.md, or analysis sidecar (#1392).","triggerScenarios":"build_from_json(extraction, root='INPUT_PATH', directed=IS_DIRECTED) yields G.number_of_nodes() == 0 because .graphify_extract.json contains no nodes: every file skipped, binary-only corpus, or upstream extraction failure.","commonSituations":"Corpus of images/binaries/lockfiles with no extractable symbols; skip patterns (vendor/, dist/, node_modules misclassified) excluding everything; extraction API call failed on quota/auth but wrote an empty JSON; wrong INPUT_PATH (empty dir).","solutions":["Verify graphify-out/.graphify_extract.json has nodes; if empty, re-run the extraction stage.","Review .graphify_detect.json to see which files were skipped and correct skip rules or the input path.","Clear .graphify_extract.json/.graphify_detect.json and re-run the full build to rule out stale empty sidecars.","Check the extraction step's token accounting (input_tokens/output_tokens) and logs for a silent upstream failure."],"exampleFix":"# before\n/graphify ./docs-pdf-only\n# ERROR: Graph is empty - extraction produced no nodes.\n\n# after\nrm graphify-out/.graphify_extract.json graphify-out/.graphify_detect.json\n/graphify ./src","handlingStrategy":"validation","validationCode":"import json\nfrom pathlib import Path\n\nextract = json.loads(Path('graphify-out/.graphify_extract.json').read_text(encoding='utf-8'))\nif not (extract.get('nodes') or []):\n    raise SystemExit('extraction empty - check skip rules / corpus before build')","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Gate the build step on a non-empty extraction sidecar.","Review the detection skip list whenever extraction comes back empty.","Verify the extraction stage's token counts/logs for silent upstream failures.","Keep sidecars and graph outputs in graphify-out/ only; never mix cwd-relative state."],"tags":["graphify","empty-graph","fail-fast","core-fragment","extraction"],"backgroundTag":null,"analyzedSha":"7fe58b0b0f3873be9a21c30106b8b8527c353aa6","analyzedAt":"2026-08-14T19:23:21.323Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}