Skip to content

[BUG] Forward references are not back-resolved when their target note is created (only on reindex) #1015

Description

@phernandez

Summary

In the new event-index architecture (#1002), creating a note that forward-references a not-yet-existing target leaves the relation unresolved, and the relation is not back-resolved when the target note is later created. Resolution only happens on a full project-index pass (bm reindex or startup indexing). This contradicts the write_note success message, which tells users:

Note: Unresolved relations point to entities that don't exist yet. They will be automatically resolved when target entities are created or during sync operations.

"during sync operations" (reindex/startup) is accurate; "when target entities are created" is not for the incremental write path.

Reproduction

Local project, fresh DB. Using write_note:

  1. Create note A with - relates_to [[Note B]] while B does not exist → A's relation is recorded unresolved (expected).
  2. Create note B.
  3. Inspect relations (recent_activity type=relation, or build_context). A's relates_to → B is still unresolved:
    • resolved relations render as A -> B with the full target permalink (.../relates-to/<project>/<b-permalink>)
    • unresolved render as just A with a short slug target (.../relates-to/note-b)
  4. Run bm reindex → the relation resolves correctly.

Observed during PR #1002 regression testing: three relations authored before their targets (Accepted -> Search Index Behavior, Accepted -> Regression Harness Session, Search Index Behavior -> Regression Harness Session) all stayed unresolved across multiple later writes, and all resolved after a single bm reindex.

Root cause

The note-write path resolves the new note's own outgoing links against existing targets, but never triggers backward resolution of other notes' dangling links pointing at the newly-created note:

  • knowledge_router note write schedules only entity_vector_sync, not a project index (src/basic_memory/api/v2/routers/knowledge_router.py:86).
  • schedule_project_index is only invoked by the project-index route command with run_in_background (src/basic_memory/deps/services.py:959) — not on note creation.
  • Single-file indexing runs with resolve_relations=False (src/basic_memory/indexing/file_indexer.py:162), so the watcher/inline single-file path doesn't back-resolve either.
  • Full relation resolution runs only in the project-index coordinator (bm reindex, startup indexing), which is why reindex fixes it.

So in normal local use (even outside test mode), a forward reference created before its target persists as unresolved until the next reindex or server restart (startup indexing). There is no periodic/triggered sweep that resolves dangling relations as targets appear.

Suggested fix

Add a lightweight background resolver that periodically (or on a debounce after writes) sweeps unresolved relations and resolves any whose targets now exist — i.e. a background/polling task rather than requiring a full bm reindex. This keeps the write_note promise true without paying for a full project-index pass on every write. It should be a no-op in test mode (consistent with the other schedulers in deps/services.py), but enabled for dev/user runtimes.

Alternative / complementary: have the accepted-note write path enqueue a targeted "resolve inbound dangling refs for this entity's title/permalink" follow-up when a note is created, so resolution is event-driven instead of polled.

If neither lands soon, update the write_note message to say resolution happens "during sync/reindex operations" and drop "when target entities are created", to avoid over-promising.

Environment

Notes

  • Should confirm whether the pre-refactor(core): add shared runtime orchestration #1002 sync architecture back-resolved these via its background relation-resolution task (the old "background relation resolution" behavior), to label this a regression vs. a known gap carried into the new architecture.

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't working

    Projects

    No projects

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions