Skip to content

Queries return wrong results with more than 65,535 uncheckpointed facts #445

Closed

Description

@adityamukho

Summary

Once a database holds more than 65,535 facts that have not been checkpointed, index-driven queries silently return wrong results. The stored data is intact.

Cause

FactStorage indexes each pending (not yet checkpointed) fact with a FactRef { page_id: 0, slot_index }, where slot_index is the fact's position in the pending vector, stored as a u16. u16::try_from(d.facts.len()).unwrap_or(u16::MAX) saturates, so every pending fact from position 65,535 on is indexed as slot 65,535. resolve_fact_ref then resolves all of them to that one fact (src/graph/storage.rs, transact, transact_batch, retract, load_fact).

Affected

  • Releases v0.7.0 through v2.0.2.
  • In-memory databases (Minigraf::in_memory) with more than 65,535 facts in total: they never checkpoint, so the results stay wrong.
  • File databases with more than 65,535 facts written since the last checkpoint: one large transact, a raised wal_checkpoint_threshold, or WAL replay of that many facts on open. A checkpoint makes the results correct again.

Symptom

Queries that go through the index paths (an entity bound in the pattern, or an attribute scan) lose or duplicate facts. Repro on v2.0.2, one transaction of 70,000 [:eN :n N] facts:

  • [:find ?v :where [:e65536 :n ?v]] returns [] (expected 65536).
  • In-memory or before a checkpoint, [:find (count ?e) (max ?v) :where [?e :n ?v]] returns 65536, 65535. After checkpoint() it returns the correct 70000, 69999.

Workaround

File databases: call checkpoint() after a large write, and keep wal_checkpoint_threshold at or below its default. In-memory databases: keep the graph at or below 65,535 facts.

Fix

Store the pending position as a usize, with no saturation. Add a regression test past 65,535 pending facts.

Activity

  1. added
    bugSomething isn't working
    known-issueBug present in a published release and not yet fixed in one; listed in the pinned known-issues issue
    on Oct 6, 2026
  2. added 2 commits that reference this issue on Oct 6, 2026
  3. adityamukho commented on Oct 6, 2026

    @adityamukho
    CollaboratorAuthor

    Reopened: closed automatically by the closing keyword in #446's description, which was a mistake. The fix is merged into main (#446); per CONTRIBUTING.md this issue stays open until the fix ships in a published v2.x release.

  4. added a commit that references this issue on Oct 6, 2026
  5. adityamukho commented on Oct 6, 2026

    @adityamukho
    CollaboratorAuthor

    Fixed in v2.0.3 (released 2026-10-06, PR #446). Upgrade to v2.0.3 or later; the file format is unchanged. Listed under "Fixed in v2.0.3" in #421.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't workingdata-integrityData integrity issueknown-issueBug present in a published release and not yet fixed in one; listed in the pinned known-issues issue

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions