You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
extract_json emits imports and extends edges whose target node is never created. build_from_json then drops those edges without a warning, because the "does not match any node id" error is explicitly filtered out of real_errors. The result is silent edge loss on two of the most common files in any JS/TS repo: package.json and tsconfig.json.
Nothing surfaces this except graphify.diagnostics.diagnose_extraction, which reports them as dangling_endpoint_edges — and by then the edges are already gone from graph.json.
grep -n 'dep_nid' extractors/json_config.py returns only those three lines: the target ID is synthesized and used as an edge endpoint, but add_node is never called for it. Same for ref_nid.
The drop is then made invisible in graphify/build.py:
real_errors= [eforeinerrorsif"does not match any node id"notine]
so the endpoint-mismatch never reaches the user.
(The $ref branch a few lines above uses the same _make_id("ref", val_text) pattern and looks like it shares the defect, but I could not exercise it: my minimal JSON-Schema test file produced zero nodes, which is #1666. Flagging it as suspected-by-inspection, not verified.)
Expected
Either of these would be self-consistent; today's behaviour is neither:
Create the node. Emit an explicit external node for the dependency / extended config (e.g. file_type: "concept", label left-pad), so the imports / extends edge lands. This is precisely the resolution already adopted for the JS/TS equivalent in JavaScript namespace re-exports emit dangling import targets #1551 ("Create a real namespace binding … and resolve the consumer import to it"), so it would make json_config consistent with the rest of the pipeline.
Given the #1551 precedent, option 1 looks right. Dependency and extends edges are genuinely useful — they are what most users would expect a package.json / tsconfig.json to contribute to the graph.
Related issues
JavaScript namespace re-exports emit dangling import targets #1551 (closed) — JavaScript namespace re-exports emit dangling import targets. Same defect class in the JS/TS extractor; fixed by creating the missing node. This report is the json_config instance of it.
Every repository with a package.json or tsconfig.json silently loses its dependency edges.
Concretely: on a 63-file repo I audited, diagnose_extraction reported 49 dangling-endpoint edges. I was able to eliminate 47 of them by re-extracting the affected documents. The remaining two were these package.jsonimports edges — unfixable from the corpus side, because no input to graphify can make the extractor create the node it points at.
Summary
extract_jsonemitsimportsandextendsedges whose target node is never created.build_from_jsonthen drops those edges without a warning, because the "does not match any node id" error is explicitly filtered out ofreal_errors. The result is silent edge loss on two of the most common files in any JS/TS repo:package.jsonandtsconfig.json.Nothing surfaces this except
graphify.diagnostics.diagnose_extraction, which reports them asdangling_endpoint_edges— and by then the edges are already gone fromgraph.json.Version
Reproduced on 0.9.11. Python 3.14.
Reproduction
Two files in an empty directory:
Actual
Nodes
left_pad,bats,ref_tsconfig_base_jsondo not exist. At build time all three edges disappear from the graph and no warning is printed.Cause
graphify/extractors/json_config.py:grep -n 'dep_nid' extractors/json_config.pyreturns only those three lines: the target ID is synthesized and used as an edge endpoint, butadd_nodeis never called for it. Same forref_nid.The drop is then made invisible in
graphify/build.py:so the endpoint-mismatch never reaches the user.
(The
$refbranch a few lines above uses the same_make_id("ref", val_text)pattern and looks like it shares the defect, but I could not exercise it: my minimal JSON-Schema test file produced zero nodes, which is #1666. Flagging it as suspected-by-inspection, not verified.)Expected
Either of these would be self-consistent; today's behaviour is neither:
file_type: "concept", labelleft-pad), so theimports/extendsedge lands. This is precisely the resolution already adopted for the JS/TS equivalent in JavaScript namespace re-exports emit dangling import targets #1551 ("Create a real namespace binding … and resolve the consumer import to it"), so it would makejson_configconsistent with the rest of the pipeline.Given the #1551 precedent, option 1 looks right. Dependency and
extendsedges are genuinely useful — they are what most users would expect apackage.json/tsconfig.jsonto contribute to the graph.Related issues
json_configinstance of it.real_errorsfilter quoted above is that mechanism. This issue is about the extractor producing the dangling edge in the first place; fixing [Bug] build_merge severs edges from UNCHANGED files into re-extracted files (−12% doc↔code in one update cycle): endpoint nodes are replaced, the surviving edges dangle, and the dangling-edge drop silently eats them #1711 would make it visible, fixing this would make it unnecessary._JSON_NOISE_LABELS), same file. Not a duplicate: that issue is about nodes that exist and rank too high, this one about a node that never exists.Same pattern elsewhere
Two other extractors synthesize an edge endpoint without creating the node:
extractors/bash.py:185—source <non-path-word>→add_edge(file_nid, _make_id(raw), "imports", ...)extractors/objc.py:169—add_edge(file_nid, _make_id(module), "imports", ...)Worth fixing as one family.
Impact
Every repository with a
package.jsonortsconfig.jsonsilently loses its dependency edges.Concretely: on a 63-file repo I audited,
diagnose_extractionreported 49 dangling-endpoint edges. I was able to eliminate 47 of them by re-extracting the affected documents. The remaining two were thesepackage.jsonimportsedges — unfixable from the corpus side, because no input to graphify can make the extractor create the node it points at.