ruvnet / ruvnet/agentdb

CausalMemoryGraph.addCausalEdge() silently creates orphan edges when NodeIdMapper.getNodeId() returns undefined

Open
#7 0 comments 0 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

Dominant language
TypeScript
Stars
89
Forks
14
PR merge metrics
No merged PRs in 30d

Description

Summary

In CausalMemoryGraph.addCausalEdge() (bundled agentdb@3.0.0-alpha.16), when NodeIdMapper.getNodeId() returns undefined for a numeric memory id that was never registered, the code constructs a fallback string ${memoryType}-${memoryId} (e.g. episode-123) and silently creates the edge — even if no node with that id exists in the graph. Surfaced by ruvnet/ruflo#2246 §3.

Where (per the reporter's read of alpha.16's dist)

// dist/controllers/CausalMemoryGraph.js — addCausalEdge()
const mapper = NodeIdMapper.getInstance();
const fromNodeId = typeof edge.fromMemoryId === 'string'
  ? edge.fromMemoryId
  : (mapper.getNodeId(edge.fromMemoryId) || `${edge.fromMemoryType}-${edge.fromMemoryId}`);
// ...same for toNodeId, then createCausalEdge(graphEdge)

The || ... fallback path runs with no console.warn, no validation, no rejection. The edge is created against an id the graph never registered → dangling/orphan edge.

Impact (from the reporter)

"We hit this as recurring causal-edge deprecation noise with no actionable guidance about required id formats (e.g. entity: / mem: prefixes)."

Silent orphans corrupt graph topology — pagerank, shortest-path, and similar traversals will encounter dangling endpoints with no diagnostic trail.

Reproduction

Call addCausalEdge() with a numeric fromMemoryId that was never registered via NodeIdMapper.register(). Observe: edge created against episode-<id> with no warning. Run a graph traversal: orphan endpoint encountered.

Suggested fix (any one)

  1. Reject the edge when the mapper returns undefined, with an actionable error message naming the missing id + the registration call.
  2. Emit console.warn documenting what id format was expected and how to register it (e.g. NodeIdMapper.register(rawId, 'entity:foo')).
  3. Validate at the end of addCausalEdge that both endpoints actually exist as nodes in the graph; reject otherwise.

Reporter's preference (#2246): "emit one actionable warning ... or reject the edge, instead of constructing an unvalidated id."

Cross-references

  • Upstream report: ruvnet/ruflo#2246 (§3 of a 4-finding bug report)
  • Bundled version that hit this: agentdb 3.0.0-alpha.16

Happy to PR if useful — start a thread.

Contributor guide

No contributing guide indexed for this repository

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Research direction

Start in dist/controllers/CausalMemoryGraph.js at addCausalEdge() and trace the NodeIdMapper.getNodeId() fallback for unregistered numeric ids. Reproduce the missing-node case, then ensure the chosen warning or rejection identifies the missing id and registration requirement; verify graph traversal no longer encounters the orphan endpoint.

Written by the indexing model from the issue text.

Assessment

Tech stack
typescript
Domain
backend, data
Issue type
Bug
Difficulty
3/5
Estimated time
1-2 days
Activity status
Quiet
Clarity
Mostly clear
Newbie friendliness
58/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.