How to Debug Validation Errors with Dangling References in Egonex AI Graphs
Run the validateGraph function from packages/core/src/schema.ts to identify exactly which edges, layers, or tour steps reference non-existent nodes, then trace the missing IDs back to your parsers or merge scripts.
Egonex AI builds a knowledge graph that undergoes strict validation before rendering in the dashboard. The validation engine in schema.ts walks the graph in three stages, removing any references to nodes that don't exist and cataloging these issues for debugging. Understanding this validation pipeline helps you pinpoint whether dangling references stem from incomplete parser output or stale merge operations.
Understanding the Validation Pipeline
The central validation logic lives in packages/core/src/schema.ts, where the validator processes the graph after initial construction but before persistence. This ensures that only valid, fully-resolved graph structures reach the UI.
The validator returns a comprehensive result object:
return { success: true, data: graph, issues, errors: buildErrors(issues) };
(see lines 62-64 of schema.ts). The issues array contains every dropped reference with its location, category, and severity level, while errors provides a formatted summary.
The Three-Stage Validation Process
The validator detects dangling references across three specific graph components:
-
Edges – Each edge's
sourceandtargetproperties must resolve to existing nodes. When a target node is missing, the validator drops the edge and logs:edges[${i}]: target "${result.data.target}" does not exist in nodes — removed(lines 601-605).
-
Layers – After collecting valid node IDs, the validator filters each layer's
nodeIdsarray to remove any IDs not present in the node set:nodeIds: result.data.nodeIds.filter((id) => nodeIds.has(id)),Invalid layers are dropped entirely (lines 611-621).
-
Tour steps – Tour steps containing
nodeIdsundergo identical filtering, with broken steps removed from the final graph (lines 632-642).
Root Causes of Dangling References
Dangling references typically appear when graph components reference node IDs that never existed or were removed during processing.
Missing node definitions occur when analyzers fail to emit a node (e.g., due to parser errors or ignore filters in ignore-filter.ts), yet edges or layers still reference that ID.
Stale graph merges happen in merge-subdomain-graphs.py or merge-batch-graphs.py when a node is removed from one subgraph but references persist in another, creating inconsistencies across the merged dataset.
Incorrect validation order can also cause issues when the validator builds the nodeIds set from already-validated nodes (validNodes), meaning any node dropped earlier in the pipeline automatically invalidates downstream references.
Step-by-Step Debugging Workflow
Follow this systematic approach to resolve validation errors in Egonex AI graphs.
Run the Validator Manually
Import validateGraph directly from schema.ts to debug outside the standard pipeline:
import { validateGraph } from '../../src/schema';
import rawGraph from '../fixtures/graph-with-dangling.json';
const result = validateGraph(rawGraph);
console.log(result.issues);
This returns the full issues array without requiring a complete application restart.
Interpret Issue Logs
Each issue entry contains a level (typically "dropped"), a category (such as "invalid-layer" or "invalid-tour-step"), a human-readable message, and the path within the JSON structure.
Look for patterns like:
edges[23]: target "abc123" does not exist in nodes — removed- Categories indicating
invalid-referenceorinvalid-layer
Trace Missing Nodes to Source
Once you identify a dangling ID:
- Check the output of
graph-builder.tsto confirm whether the node ever existed in the raw graph. - If the node is missing, examine the relevant language parser or analyzer to determine why it was filtered out.
- If the node should exist but doesn't, verify
merge-subdomain-graphs.pyormerge-batch-graphs.pylogic to ensure consistent node removal across all references.
Writing Reproduction Tests
Create targeted tests to prevent regression of dangling reference issues. The test suite in packages/core/src/__tests__/normalize-graph.test.ts provides a pattern for asserting validation behavior:
import { validateGraph } from '../../src/schema';
import rawGraph from '../fixtures/graph-with-dangling.json';
test('validation drops dangling edges', () => {
const result = validateGraph(rawGraph);
expect(result.issues).toContainEqual(
expect.objectContaining({ category: 'invalid-reference' })
);
expect(result.data.edges).toHaveLength(expectedEdgeCount);
});
Running these tests alongside the integration tests in tests/skill/understand/test_merge_batch_graphs.py ensures that batch merging operations don't introduce dangling references.
Summary
- Validation occurs in three stages in
schema.ts: edges (lines 601-605), layers (lines 611-621), and tour steps (lines 632-642). - Dangling references indicate missing nodes, stale merge data, or premature node filtering.
- Debug by running
validateGraphmanually and inspecting theissuesarray for specific path and category information. - Fix upstream in
graph-builder.ts, language parsers, or merge scripts (merge-subdomain-graphs.py,merge-batch-graphs.py). - Test fixes using
normalize-graph.test.tspatterns to ensure dangling edges are properly handled.
Frequently Asked Questions
What does "dangling reference" mean in Egonex AI graphs?
A dangling reference occurs when an edge, layer, or tour step points to a node ID that doesn't exist in the graph's node set. According to the schema.ts validation logic, these references are automatically removed and logged as issues with the category invalid-reference or similar.
Why do my graph layers disappear after validation?
Layers disappear when their nodeIds array contains IDs not present in the validated node set. The validator filters each layer's nodes using nodeIds.filter((id) => nodeIds.has(id)) (lines 611-621), and if the layer fails subsequent schema validation, it is dropped entirely. Check the issues array for invalid-layer entries to identify which node IDs are missing.
How can I prevent dangling references during graph merges?
When using merge-subdomain-graphs.py or merge-batch-graphs.py, ensure that node removal operations propagate to all referencing edges, layers, and tour steps before the final validation step. Run the validateGraph function after merging to catch any inconsistencies immediately, and add assertions in test_merge_batch_graphs.py to verify reference integrity across subgraph boundaries.
Where can I find examples of handled dangling references in the codebase?
The normalize-graph.test.ts file contains unit tests demonstrating how the validator handles dangling edges and references. Additionally, test_merge_batch_graphs.py shows integration-level scenarios where batch merging might create dangling references, providing practical examples of validation error patterns and their resolutions.
Have a question about this repo?
These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:
curl -s "https://instagit.com/install.md" Maintain an open-source project? Get it listed too →